diff --git a/Gemfile b/Gemfile
index cb6d11592f9f9011ed309662023d43129259d512..a1af70f747f5e4adeea50bef548e40dfbe9aed0b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -8,10 +8,10 @@ gem 'bundler', '>= 1.0.0'
 gem 'chef', '0.9.12', :require => false
 gem 'ohai', '0.5.8', :require => false #Chef dependency
 
-gem 'nokogiri', '1.4.3.1'
+gem 'nokogiri'
 
 #Security
-gem 'devise', '1.3.1'
+gem 'devise', '~> 1.3.1'
 gem 'devise_invitable', '0.5.0'
 
 #Authentication
@@ -61,7 +61,7 @@ gem 'SystemTimer', '1.2.1' unless RUBY_VERSION.include? '1.9' || RUBY_PLATFORM =
 group :development do
   gem 'capistrano', '2.5.19', :require => false
   gem 'capistrano-ext', '1.2.1', :require => false
-  gem 'sod', :git => "git://github.com/MikeSofaer/sod.git"
+  gem 'sod', :git => "git://github.com/MikeSofaer/sod.git", :require => false
 end
 
 group :test, :development do
@@ -80,7 +80,7 @@ group :test do
   gem 'cucumber-rails', '0.3.2'
   gem 'rspec', '>= 2.0.0'
   gem 'rspec-rails', '>= 2.0.0'
-  gem 'rcov'
+  gem 'rcov', :require => false
   gem 'database_cleaner', '0.6.0'
   gem 'webmock', :require => false
   gem 'jasmine', :path => 'vendor/gems/jasmine', :require => false
diff --git a/Gemfile.lock b/Gemfile.lock
index 4c14681c6b5fad3a9d5eb70ac527bd789b448f84..d8ae9821405453d7c74d655f462925ba3e7ef2e7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -156,9 +156,9 @@ GEM
     cucumber-rails (0.3.2)
       cucumber (>= 0.8.0)
     culerity (0.2.15)
-    daemons (1.1.2)
+    daemons (1.1.3)
     database_cleaner (0.6.0)
-    devise (1.3.1)
+    devise (1.3.4)
       bcrypt-ruby (~> 2.1.2)
       orm_adapter (~> 0.0.3)
       warden (~> 1.0.3)
@@ -185,7 +185,7 @@ GEM
     fastthread (1.0.7)
     ffi (0.6.3)
       rake (>= 0.8.7)
-    fixture_builder (0.2.0)
+    fixture_builder (0.2.2)
     fog (0.3.25)
       builder
       excon (>= 0.2.4)
@@ -202,12 +202,12 @@ GEM
       rspec (~> 2.0)
       rspec-instafail (~> 0.1.4)
     gem_plugin (0.2.3)
-    gherkin (2.3.6)
+    gherkin (2.3.8)
       json (>= 1.4.6)
     haml (3.0.25)
     hashie (0.4.0)
-    highline (1.6.1)
-    http_connection (1.4.0)
+    highline (1.6.2)
+    http_connection (1.4.1)
     i18n (0.5.0)
     i18n-inflector (2.5.1)
       i18n (>= 0.4.1)
@@ -224,7 +224,7 @@ GEM
       configuration (>= 0.0.5)
       rake (>= 0.8.1)
     linecache (0.43)
-    mail (2.2.15)
+    mail (2.2.19)
       activesupport (>= 2.3.6)
       i18n (>= 0.4.0)
       mime-types (~> 1.16)
@@ -245,7 +245,7 @@ GEM
       gem_plugin (>= 0.2.3)
     multi_json (0.0.5)
     multi_xml (0.2.2)
-    multipart-post (1.1.0)
+    multipart-post (1.1.1)
     mysql2 (0.2.6)
     net-ldap (0.1.1)
     net-scp (1.0.4)
@@ -253,7 +253,7 @@ GEM
     net-sftp (2.0.5)
       net-ssh (>= 2.0.9)
     net-ssh (2.0.24)
-    net-ssh-gateway (1.0.1)
+    net-ssh-gateway (1.1.0)
       net-ssh (>= 1.99.1)
     nokogiri (1.4.3.1)
     oa-basic (0.1.6)
@@ -366,8 +366,8 @@ GEM
       ffi (~> 0.6.3)
       json_pure
       rubyzip
-    simple_oauth (0.1.4)
-    sinatra (1.2.3)
+    simple_oauth (0.1.5)
+    sinatra (1.2.6)
       rack (~> 1.1)
       tilt (< 2.0, >= 1.2.2)
     subexec (0.0.4)
@@ -378,7 +378,7 @@ GEM
       eventmachine (>= 0.12.6)
       rack (>= 1.0.0)
     thor (0.14.6)
-    tilt (1.2.2)
+    tilt (1.3)
     treetop (1.4.9)
       polyglot (>= 0.3.1)
     typhoeus (0.2.4)
@@ -415,7 +415,7 @@ DEPENDENCIES
   cloudfiles (= 1.4.10)
   cucumber-rails (= 0.3.2)
   database_cleaner (= 0.6.0)
-  devise (= 1.3.1)
+  devise (~> 1.3.1)
   devise_invitable (= 0.5.0)
   em-websocket!
   excon (= 0.2.4)
@@ -435,7 +435,7 @@ DEPENDENCIES
   mini_magick (= 3.2)
   mongrel
   mysql2 (= 0.2.6)
-  nokogiri (= 1.4.3.1)
+  nokogiri
   ohai (= 0.5.8)
   omniauth (= 0.1.6)
   rails (= 3.0.3)
diff --git a/README.md b/README.md
index 3770c2d47e791b378eefcb24e62cb0f4b1329e1b..c03feba7c51914e3c35d113037f7b2c4fd32aa09 100644
--- a/README.md
+++ b/README.md
@@ -42,10 +42,10 @@ See [here](http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.
 for when to rebase.
 
 We need you to fill out a
-[contributor agreement form](https://spreadsheets.google.com/a/joindiaspora.com/viewform?formkey=dGI2cHA3ZnNHLTJvbm10LUhXRTJjR0E6MQ&theme=0AX42CRMsmRFbUy1iOGYwN2U2Mi1hNWU0LTRlNjEtYWMyOC1lZmU4ODg1ODc1ODI&ifq)
+[contributor agreement form](https://spreadsheets.google.com/a/joindiaspora.com/spreadsheet/viewform?formkey=dFdRTnY0TGtfaklKQXZNUndsMlJ2eGc6MQ)
 before we can accept your patches.  The agreement gives Diaspora joint
 ownership of the patch so the copyright isn't scattered.  You can find it
-[here](https://spreadsheets.google.com/a/joindiaspora.com/viewform?formkey=dGI2cHA3ZnNHLTJvbm10LUhXRTJjR0E6MQ&theme=0AX42CRMsmRFbUy1iOGYwN2U2Mi1hNWU0LTRlNjEtYWMyOC1lZmU4ODg1ODc1ODI&ifq).
+[here](https://spreadsheets.google.com/a/joindiaspora.com/spreadsheet/viewform?formkey=dFdRTnY0TGtfaklKQXZNUndsMlJ2eGc6MQ).
 We're currently working on revising it more details on what we're going for can be found [here](http://blog.joindiaspora.com/licensing.html).
 
 ## Resources
@@ -73,4 +73,4 @@ Also, be sure to join the official [mailing list](http://eepurl.com/Vebk).
 
 If you wish to contact us privately about any exploits in Diaspora you may
 find, you can email
-[exploits@joindiaspora.com](mailto:exploits@joindiaspora.com), [corresponding public key (keyID: 77485064)](http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0xCC6CAED977485064).
\ No newline at end of file
+[exploits@joindiaspora.com](mailto:exploits@joindiaspora.com), [corresponding public key (keyID: 77485064)](http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0xCC6CAED977485064).
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 0e16c5f2729d10fff7918724e3233c9604c03640..bd76960a907957c5b9018e3cf4b8054d77d440b8 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -103,4 +103,8 @@ class ApplicationController < ActionController::Base
   def grammatical_gender
     @grammatical_gender || nil
   end
+
+  def after_sign_in_path_for(resource)
+      stored_location_for(:user) || aspects_path(:a_ids => current_user.aspects.where(:open => true).select(:id).all.map{|a| a.id})
+  end
 end
diff --git a/app/views/js/_websocket_js.haml b/app/views/js/_websocket_js.haml
index 4187ff6318d82a1e5a745c85d3d6336b15c37102..f021fb1c1c06dcf0ad7358e7e6e421c5c9196128 100644
--- a/app/views/js/_websocket_js.haml
+++ b/app/views/js/_websocket_js.haml
@@ -2,9 +2,13 @@
 -#   licensed under the Affero General Public License version 3 or later.  See
 -#   the COPYRIGHT file.
 
-:javascript
-  WebSocket.__swfLocation = "#{javascript_path 'vendor/WebSocketMain.swf'}";
-  $(document).ready(function(){
-    WSR.initialize("#{(AppConfig[:socket_secure])?'wss':'ws'}://#{request.host}:#{AppConfig[:socket_port]}/");
-  });
- 
+-if AppConfig[:single_process_mode]
+  :javascript
+    var websocket_enabled = false
+- else
+  :javascript
+    var websocket_enabled = true
+    WebSocket.__swfLocation = "#{javascript_path 'vendor/WebSocketMain.swf'}";
+    $(document).ready(function(){
+      WSR.initialize("#{(AppConfig[:socket_secure])?'wss':'ws'}://#{request.host}:#{AppConfig[:socket_port]}/");
+    });
diff --git a/config/app_config.yml.example b/config/app_config.yml.example
index 8d3c1ec47ac1bfbc4630f379614075daa4503270..393b6e53dc7dbf3fc95a51d5820967d718dd6b1a 100644
--- a/config/app_config.yml.example
+++ b/config/app_config.yml.example
@@ -96,6 +96,9 @@ default:
   # It is false by default in development and test.
   enable_splunk_logging: true
 
+  # Process jobs in process?
+  single_process_mode: true
+
 development:
   enable_splunk_logging: false
 
@@ -105,3 +108,4 @@ test:
   enable_splunk_logging: false
 
 production:
+  single_process_mode: false
diff --git a/config/initializers/resque.rb b/config/initializers/resque.rb
index 94fe55ac459cc100772bf50214f173f370b2d879..cc977ba6a00c84aa652583ebfc8e7d6ed0db3b34 100644
--- a/config/initializers/resque.rb
+++ b/config/initializers/resque.rb
@@ -1,5 +1,20 @@
 require File.join(Rails.root, 'app', 'models', 'jobs', 'base')
 Dir[File.join(Rails.root, 'app', 'models', 'jobs', '*.rb')].each { |file| require file }
-#config = YAML::load(File.open("#{Rails.root}/config/redis.yml"))
-#Resque.redis = Redis.new(:host => config['host'], :port => config['port'])
+
 require 'resque'
+
+begin
+  if AppConfig[:single_process_mode]
+    if Rails.env == 'production'
+      puts "WARNING: You are running Diaspora in production without Resque workers turned on.  Please don't do this."
+    end
+
+    module Resque
+      def enqueue(klass, *args)
+        klass.send(:perform, *args)
+      end
+    end
+  end
+rescue
+  nil
+end
diff --git a/config/server.sh b/config/server.sh
index 7398b2fd892c3baf5f0ddcf56ac3a7744f79593e..7060a9f5c13cc1b8fe21f89c3d28c2fe52655058 100644
--- a/config/server.sh
+++ b/config/server.sh
@@ -2,7 +2,6 @@
 # Included by script/server
 #
 THIN_PORT=3000
-SOCKET_PORT=8080
 
 # Choose one mode by uncommenting
 export RAILS_ENV='development'
diff --git a/db/schema.rb b/db/schema.rb
index ef1b635f65c56b30b1f4e3bfef6cf7db5f088c47..0022f75eccfef30b6d05a498f57cef54763780f2 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20110514182918) do
+ActiveRecord::Schema.define(:version => 20110517180148) do
 
   create_table "aspect_memberships", :force => true do |t|
     t.integer  "aspect_id",  :null => false
diff --git a/features/change_password.feature b/features/change_password.feature
index aeb80bad23faac17d4e9011728f2cd14d17bf8f0..31da98c01cc748a41f2bfd3b6fd8c3d27b2e000e 100644
--- a/features/change_password.feature
+++ b/features/change_password.feature
@@ -14,3 +14,16 @@ Feature: Change password
     Then I should be on the new user session page
     When I sign in with password "newsecret"
     Then I should be on the aspects page
+
+  Scenario: Reset my password
+    Given a user with email "forgetful@users.net"
+    Given I am on the new user password page
+    And I fill in "Email" with "forgetful@users.net"
+    And I press "Send me reset password instructions"
+    Then I should see "You will receive an email with instructions"
+    And I follow the "Change my password" link from the Devise.mailer
+    Then I should see "Change your password"
+    And I fill in "Password" with "supersecret"
+    And I fill in "Password confirmation" with "supersecret"
+    And I press "Change my password"
+    Then I should see "Your password was changed successfully"
diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb
index d14830bb3b19b31e1948fd174c9676e798b75f96..f327e463e2e707cde61eadd908bf59cb2e7512f2 100644
--- a/features/step_definitions/user_steps.rb
+++ b/features/step_definitions/user_steps.rb
@@ -187,3 +187,11 @@ When /^I add the person to a new aspect called "([^\"]*)"$/ do |aspect_name|
     And I press the first ".toggle.button"
   }
 end
+
+And /^I follow the "([^\"]*)" link from the Devise.mailer$/ do |link_text|
+  doc = Nokogiri(Devise.mailer.deliveries.first.body.to_s)
+  links = doc.css('a')
+  link = links.detect{ |link| link.text == link_text }
+  path = link.attributes["href"].value
+  visit URI::parse(path).request_uri
+end
diff --git a/features/support/env.rb b/features/support/env.rb
index 09827a3f5a29d38a190dc400683c0e7d456230e3..b0bb208b8ddf85161f09bc1b20ed3bc91b91f950 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -48,6 +48,7 @@ include HelperMethods
 
 Before do
   DatabaseCleaner.clean
+  Devise.mailer.deliveries = []
 end
 
 silence_warnings do
diff --git a/lib/app_config.rb b/lib/app_config.rb
index 7fefcf93de361253ea43e76cfdb353b300629aaf..53ad6de8c186063a5201f04019a05f0782269760 100644
--- a/lib/app_config.rb
+++ b/lib/app_config.rb
@@ -1,4 +1,4 @@
-# Copyright (c) 2010, Diaspora Inc.  This file is
+# Copyright (c) 2011, Diaspora Inc.  This file is
 # licensed under the Affero General Public License version 3 or later.  See
 # the COPYRIGHT file.
 
@@ -14,6 +14,10 @@ class AppConfig
     config_vars[key] = value
   end
 
+  def self.has_key?(key)
+    config_vars.has_key?(key)
+  end
+
   def self.configure_for_environment(env)
     load_config_for_environment(env)
     generate_pod_uri
diff --git a/lib/diaspora/web_socket.rb b/lib/diaspora/web_socket.rb
index f27527ca8ac791cf4620fdbf094efec666ea80b4..9df317df22092122f72fa9307a29c777cb49c4c4 100644
--- a/lib/diaspora/web_socket.rb
+++ b/lib/diaspora/web_socket.rb
@@ -60,11 +60,19 @@ module Diaspora
 
   module Socketable
     def socket_to_user(user_or_id, opts={})
-      SocketsController.new.outgoing(user_or_id, self, opts)
+      begin
+        SocketsController.new.outgoing(user_or_id, self, opts)
+      rescue
+        nil
+      end
     end
 
     def unsocket_from_user(user_or_id, opts={})
-      SocketsController.new.outgoing(user_or_id, Retraction.for(self), opts)
+      begin
+        SocketsController.new.outgoing(user_or_id, Retraction.for(self), opts)
+      rescue
+        nil
+      end
     end
   end
 end
diff --git a/public/javascripts/web-socket-receiver.js b/public/javascripts/web-socket-receiver.js
index e0ad2349c668f11dd1bd05c18899e2b4c1cb0ba4..70a448adf0e1ae66b52aef35b99936dab2130fe3 100644
--- a/public/javascripts/web-socket-receiver.js
+++ b/public/javascripts/web-socket-receiver.js
@@ -6,14 +6,16 @@ var WebSocketReceiver = {
     //Attach onmessage to websocket
     ws.onmessage = WSR.onMessage;
     ws.onclose = function() {
-      Diaspora.widgets.notifications.showNotification({
-        html: '<div class="notification">' +
-            Diaspora.widgets.i18n.t("web_sockets.disconnected") +
-          '</div>',
-        incrementCount: false
-      });
-
-      WSR.debug("socket closed");
+      if (websocket_enabled) {
+        Diaspora.widgets.notifications.showNotification({
+          html: '<div class="notification">' +
+              Diaspora.widgets.i18n.t("web_sockets.disconnected") +
+            '</div>',
+          incrementCount: false
+        });
+
+        WSR.debug("socket closed");
+      }
     };
     ws.onopen = function() {
       ws.send(location.pathname);
diff --git a/script/get_config.rb b/script/get_config.rb
new file mode 100755
index 0000000000000000000000000000000000000000..1f006796507de90d02517ede279fde7dc1bcdb4d
--- /dev/null
+++ b/script/get_config.rb
@@ -0,0 +1,42 @@
+#!/usr/bin/env ruby
+# Copyright (c) 2011, Diaspora Inc.  This file is
+# licensed under the Affero General Public License version 3 or later.  See
+# the COPYRIGHT file.
+
+require 'rubygems'
+require 'yaml'
+
+require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/hash/keys'
+
+class Rails
+  def self.root
+    File.join(File.dirname(__FILE__), "..")
+  end
+  
+  def self.env
+    env = 'development'
+    env = ENV['RAILS_ENV'] if ENV.has_key?('RAILS_ENV')
+    env = ARGV[1] if ARGV.length == 2
+    env.downcase
+  end
+end
+
+require File.join(Rails.root, 'lib', 'app_config')
+
+
+if ARGV.length >= 1
+  key = ARGV[0].to_sym
+  AppConfig.configure_for_environment(Rails.env)
+  if AppConfig.has_key?(key)
+    print AppConfig[key]
+  else
+    puts "Invalid option #{ARGV[0]}"
+    exit 2
+  end
+else
+  puts "Usage: ./script/get_config.rb option [environment]"
+  puts ""
+  puts "envrionment defaults to development"
+  exit 1
+end
diff --git a/script/server b/script/server
index f2a2d28432da0449e2f223861e07244466535a14..714cb81774c85c525a241ab98c347ed938fd9e90 100755
--- a/script/server
+++ b/script/server
@@ -10,6 +10,7 @@ OS=`uname -s`
 
 [ -e config/server.sh ] && source config/server.sh
 
+export SOCKET_PORT=$(./script/get_config.rb socket_port $RAILS_ENV)
 
 function init_public
 # Create all dynamically generated files in public/ folder
@@ -121,10 +122,6 @@ if [ -n "$services" ]; then
     exit 64
 fi
 
-
-redis_config
-
-
 # Force AGPL
 if [ -w public -a ! -e  public/source.tar.gz ]; then
     branch=$( git branch | awk '/^[*]/ {print $2}')
@@ -169,7 +166,12 @@ if [ ! -e 'public/assets/default.css' ]; then
 fi
 
 mkdir -p -v log/thin/
-bundle exec ruby ./script/websocket_server.rb&
-redis-server config/redis.conf &>log/redis-console.log &
-QUEUE=* bundle exec rake resque:work&
+if [ "$(./script/get_config.rb single_process_mode $RAILS_ENV)" = "false" ]; then
+    redis_config
+    redis-server config/redis.conf &>log/redis-console.log &
+
+    QUEUE=* bundle exec rake resque:work&
+    
+    bundle exec ruby ./script/websocket_server.rb&
+fi
 bundle exec thin start $args
diff --git a/script/websocket_server.rb b/script/websocket_server.rb
index 040070d00969b9668788bfdae4eea4c31bdf3d5c..8dde9c58fd19dbc4e4f09c7b8c38d7f6afbdd385 100644
--- a/script/websocket_server.rb
+++ b/script/websocket_server.rb
@@ -69,7 +69,7 @@ begin
 
           debug_pp cookie
 
-          user_id = cookie["warden.user.user.key"].last
+          user_id = cookie["warden.user.user.key"][1].first
 
           debug_pp "In WSS, suscribing user: #{User.find(user_id).name} with id: #{user_id}"
           sid = Diaspora::WebSocket.subscribe(user_id, ws)
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 99256d3b14c5769429d969f0b884a402dfd836de..f6cc2deaeaab08038ffa5ddbbf419cf622ce3e44 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -63,9 +63,10 @@ describe RegistrationsController do
         flash[:notice].should_not be_empty
       end
 
-      it "redirects to the root path" do
+      it "redirects to the home path" do
         get :create, @valid_params
-        response.should redirect_to root_path
+        response.should be_redirect
+        response.location.should match /^#{aspects_url}\??$/
       end
     end
 
@@ -99,4 +100,4 @@ describe RegistrationsController do
       end
     end
   end
-end
\ No newline at end of file
+end
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 3337787e5c2ea5520183f0bbbfbee3380ca77484..f7b9a133bf19a3e1d0620a417b6a7d13f202f405 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -24,15 +24,17 @@ describe SessionsController do
   end
 
   describe "#create" do
-    it "redirects to / for a non-mobile user" do
+    it "redirects to /aspects for a non-mobile user" do
       post :create, {"user" => {"remember_me" => "0", "username" => @user.username, "password" => "evankorth"}}
-      response.should redirect_to root_path
+      response.should be_redirect
+      response.location.should match /^#{aspects_url}\??$/
     end
 
-    it "redirects to / for a mobile user" do
+    it "redirects to /aspects for a mobile user" do
       @request.env['HTTP_USER_AGENT'] = 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7'
       post :create, {"user" => {"remember_me" => "0", "username" => @user.username, "password" => "evankorth"}}
-      response.should redirect_to root_path
+      response.should be_redirect
+      response.location.should match /^#{aspects_url}\??$/
     end
 
     it 'queues up an update job' do
@@ -59,4 +61,4 @@ describe SessionsController do
       response.should redirect_to root_path
     end
   end
-end
\ No newline at end of file
+end
diff --git a/spec/lib/diaspora/web_socket_spec.rb b/spec/lib/diaspora/web_socket_spec.rb
index 551b874d0ed3ba370bfe650483cac0929f110b25..37fda4e684d5911c6ca18c789ec99a5a81ab7989 100644
--- a/spec/lib/diaspora/web_socket_spec.rb
+++ b/spec/lib/diaspora/web_socket_spec.rb
@@ -63,4 +63,11 @@ describe Diaspora::Socketable do
     Diaspora::WebSocket.should_receive(:queue_to_user)
     @post.socket_to_user(@user, :aspect_ids => @aspect.id)
   end
+
+  it 'no-ops if redis isnt present' do
+    Diaspora::WebSocket.stub(:redis).and_return(nil)
+    lambda {
+      @post.socket_to_user(@user, :aspect_ids => @aspect.id)
+    }.should_not raise_error
+  end
 end