accounts 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/.rvmrc +53 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +167 -0
- data/README.mkd +105 -0
- data/Rakefile +24 -0
- data/accounts.gemspec +52 -0
- data/demo/views/change_email.haml +14 -0
- data/demo/views/change_password.haml +36 -0
- data/demo/views/forgot_password.haml +21 -0
- data/demo/views/logon.haml +24 -0
- data/demo/views/register.haml +15 -0
- data/demo/web_app.rb +99 -0
- data/features/change-email.feature +51 -0
- data/features/change-password.feature +89 -0
- data/features/register.feature +42 -0
- data/features/step_definitions/steps.rb +102 -0
- data/features/step_definitions/web_steps.rb +228 -0
- data/features/support/env.rb +18 -0
- data/features/support/paths.rb +29 -0
- data/features/support/unused.rb +29 -0
- data/lib/accounts.rb +79 -0
- data/lib/accounts/configure.rb +122 -0
- data/lib/accounts/helpers.rb +90 -0
- data/lib/accounts/model.rb +126 -0
- data/lib/accounts/version.rb +5 -0
- data/spec/user_model_spec.rb +105 -0
- metadata +263 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
|
7
|
+
environment_id="ruby-1.9.2-p290@accounts"
|
8
|
+
|
9
|
+
#
|
10
|
+
# Uncomment following line if you want options to be set only for given project.
|
11
|
+
#
|
12
|
+
# PROJECT_JRUBY_OPTS=( --1.9 )
|
13
|
+
|
14
|
+
#
|
15
|
+
# First we attempt to load the desired environment directly from the environment
|
16
|
+
# file. This is very fast and efficient compared to running through the entire
|
17
|
+
# CLI and selector. If you want feedback on which environment was used then
|
18
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
19
|
+
#
|
20
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
21
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
22
|
+
then
|
23
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
24
|
+
|
25
|
+
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
|
26
|
+
then
|
27
|
+
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
28
|
+
fi
|
29
|
+
else
|
30
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
31
|
+
if ! rvm --create "$environment_id"
|
32
|
+
then
|
33
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
34
|
+
exit 1
|
35
|
+
fi
|
36
|
+
fi
|
37
|
+
|
38
|
+
#
|
39
|
+
# If you use an RVM gemset file to install a list of gems (*.gems), you can have
|
40
|
+
# it be automatically loaded. Uncomment the following and adjust the filename if
|
41
|
+
# necessary.
|
42
|
+
#
|
43
|
+
#filename=".gems"
|
44
|
+
filename="Gemfile"
|
45
|
+
if false && [[ -s "$filename" ]] ; then
|
46
|
+
rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
|
47
|
+
fi
|
48
|
+
|
49
|
+
# If you use bundler, this might be useful to you:
|
50
|
+
if command -v bundle && [[ -s Gemfile ]] ; then
|
51
|
+
bundle install
|
52
|
+
fi
|
53
|
+
rvm current
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
accounts (0.0.1)
|
5
|
+
data_mapper
|
6
|
+
dm-postgres-adapter
|
7
|
+
dm-timestamps
|
8
|
+
dm-types
|
9
|
+
logger
|
10
|
+
mail
|
11
|
+
rack (~> 1.3.6)
|
12
|
+
sinatra
|
13
|
+
thin
|
14
|
+
|
15
|
+
GEM
|
16
|
+
remote: http://rubygems.org/
|
17
|
+
specs:
|
18
|
+
addressable (2.2.6)
|
19
|
+
backports (2.3.0)
|
20
|
+
bcrypt-ruby (3.0.1)
|
21
|
+
builder (3.0.0)
|
22
|
+
capybara (1.1.2)
|
23
|
+
mime-types (>= 1.16)
|
24
|
+
nokogiri (>= 1.3.3)
|
25
|
+
rack (>= 1.0.0)
|
26
|
+
rack-test (>= 0.5.4)
|
27
|
+
selenium-webdriver (~> 2.0)
|
28
|
+
xpath (~> 0.1.4)
|
29
|
+
childprocess (0.2.4)
|
30
|
+
ffi (~> 1.0.6)
|
31
|
+
cucumber (1.1.4)
|
32
|
+
builder (>= 2.1.2)
|
33
|
+
diff-lcs (>= 1.1.2)
|
34
|
+
gherkin (~> 2.7.1)
|
35
|
+
json (>= 1.4.6)
|
36
|
+
term-ansicolor (>= 1.0.6)
|
37
|
+
daemons (1.1.5)
|
38
|
+
data_mapper (1.2.0)
|
39
|
+
dm-aggregates (~> 1.2.0)
|
40
|
+
dm-constraints (~> 1.2.0)
|
41
|
+
dm-core (~> 1.2.0)
|
42
|
+
dm-migrations (~> 1.2.0)
|
43
|
+
dm-serializer (~> 1.2.0)
|
44
|
+
dm-timestamps (~> 1.2.0)
|
45
|
+
dm-transactions (~> 1.2.0)
|
46
|
+
dm-types (~> 1.2.0)
|
47
|
+
dm-validations (~> 1.2.0)
|
48
|
+
data_objects (0.10.7)
|
49
|
+
addressable (~> 2.1)
|
50
|
+
diff-lcs (1.1.3)
|
51
|
+
dm-aggregates (1.2.0)
|
52
|
+
dm-core (~> 1.2.0)
|
53
|
+
dm-constraints (1.2.0)
|
54
|
+
dm-core (~> 1.2.0)
|
55
|
+
dm-core (1.2.0)
|
56
|
+
addressable (~> 2.2.6)
|
57
|
+
dm-do-adapter (1.2.0)
|
58
|
+
data_objects (~> 0.10.6)
|
59
|
+
dm-core (~> 1.2.0)
|
60
|
+
dm-migrations (1.2.0)
|
61
|
+
dm-core (~> 1.2.0)
|
62
|
+
dm-postgres-adapter (1.2.0)
|
63
|
+
dm-do-adapter (~> 1.2.0)
|
64
|
+
do_postgres (~> 0.10.6)
|
65
|
+
dm-serializer (1.2.1)
|
66
|
+
dm-core (~> 1.2.0)
|
67
|
+
fastercsv (~> 1.5.4)
|
68
|
+
json (~> 1.6.1)
|
69
|
+
json_pure (~> 1.6.1)
|
70
|
+
multi_json (~> 1.0.3)
|
71
|
+
dm-timestamps (1.2.0)
|
72
|
+
dm-core (~> 1.2.0)
|
73
|
+
dm-transactions (1.2.0)
|
74
|
+
dm-core (~> 1.2.0)
|
75
|
+
dm-types (1.2.1)
|
76
|
+
bcrypt-ruby (~> 3.0.0)
|
77
|
+
dm-core (~> 1.2.0)
|
78
|
+
fastercsv (~> 1.5.4)
|
79
|
+
json (~> 1.6.1)
|
80
|
+
multi_json (~> 1.0.3)
|
81
|
+
stringex (~> 1.3.0)
|
82
|
+
uuidtools (~> 2.1.2)
|
83
|
+
dm-validations (1.2.0)
|
84
|
+
dm-core (~> 1.2.0)
|
85
|
+
do_postgres (0.10.7)
|
86
|
+
data_objects (= 0.10.7)
|
87
|
+
eventmachine (0.12.10)
|
88
|
+
fastercsv (1.5.4)
|
89
|
+
ffi (1.0.11)
|
90
|
+
gherkin (2.7.1)
|
91
|
+
json (>= 1.4.6)
|
92
|
+
haml (3.1.4)
|
93
|
+
i18n (0.6.0)
|
94
|
+
json (1.6.4)
|
95
|
+
json_pure (1.6.4)
|
96
|
+
logger (1.2.8)
|
97
|
+
mail (2.3.0)
|
98
|
+
i18n (>= 0.4.0)
|
99
|
+
mime-types (~> 1.16)
|
100
|
+
treetop (~> 1.4.8)
|
101
|
+
mail-single_file_delivery (0.0.1)
|
102
|
+
mail
|
103
|
+
mail-store-agent (0.1.1)
|
104
|
+
mail
|
105
|
+
mime-types (1.17.2)
|
106
|
+
multi_json (1.0.4)
|
107
|
+
nokogiri (1.5.0)
|
108
|
+
polyglot (0.3.3)
|
109
|
+
rack (1.3.6)
|
110
|
+
rack-protection (1.2.0)
|
111
|
+
rack
|
112
|
+
rack-test (0.6.1)
|
113
|
+
rack (>= 1.0)
|
114
|
+
rdoc (3.12)
|
115
|
+
json (~> 1.4)
|
116
|
+
rspec (2.7.0)
|
117
|
+
rspec-core (~> 2.7.0)
|
118
|
+
rspec-expectations (~> 2.7.0)
|
119
|
+
rspec-mocks (~> 2.7.0)
|
120
|
+
rspec-core (2.7.1)
|
121
|
+
rspec-expectations (2.7.0)
|
122
|
+
diff-lcs (~> 1.1.2)
|
123
|
+
rspec-mocks (2.7.0)
|
124
|
+
rubyzip (0.9.5)
|
125
|
+
selenium-webdriver (2.15.0)
|
126
|
+
childprocess (>= 0.2.1)
|
127
|
+
ffi (~> 1.0.9)
|
128
|
+
multi_json (~> 1.0.4)
|
129
|
+
rubyzip
|
130
|
+
sinatra (1.3.2)
|
131
|
+
rack (~> 1.3, >= 1.3.6)
|
132
|
+
rack-protection (~> 1.2)
|
133
|
+
tilt (~> 1.3, >= 1.3.3)
|
134
|
+
sinatra-contrib (1.3.1)
|
135
|
+
backports (>= 2.0)
|
136
|
+
eventmachine
|
137
|
+
rack-protection
|
138
|
+
rack-test
|
139
|
+
sinatra (~> 1.3.0)
|
140
|
+
tilt (~> 1.3)
|
141
|
+
stringex (1.3.0)
|
142
|
+
term-ansicolor (1.0.7)
|
143
|
+
thin (1.3.1)
|
144
|
+
daemons (>= 1.0.9)
|
145
|
+
eventmachine (>= 0.12.6)
|
146
|
+
rack (>= 1.0.0)
|
147
|
+
tilt (1.3.3)
|
148
|
+
treetop (1.4.10)
|
149
|
+
polyglot
|
150
|
+
polyglot (>= 0.3.1)
|
151
|
+
uuidtools (2.1.2)
|
152
|
+
xpath (0.1.4)
|
153
|
+
nokogiri (~> 1.3)
|
154
|
+
|
155
|
+
PLATFORMS
|
156
|
+
ruby
|
157
|
+
|
158
|
+
DEPENDENCIES
|
159
|
+
accounts!
|
160
|
+
capybara
|
161
|
+
cucumber
|
162
|
+
haml
|
163
|
+
mail-single_file_delivery
|
164
|
+
mail-store-agent
|
165
|
+
rdoc
|
166
|
+
rspec
|
167
|
+
sinatra-contrib
|
data/README.mkd
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Accounts
|
2
|
+
|
3
|
+
## Summary
|
4
|
+
*accounts* is a website plug-in that offers than the basic user-account management
|
5
|
+
and authentication features that many sites need.
|
6
|
+
|
7
|
+
## Background
|
8
|
+
|
9
|
+
Most sites I've built require a user authentication and user-account management features.
|
10
|
+
These include:
|
11
|
+
* Registering a new user
|
12
|
+
* Authenticating (logging-on)
|
13
|
+
* Verifying a user's e-mail
|
14
|
+
* Modifying a user's e-mail
|
15
|
+
* Resetting a user's password
|
16
|
+
* Suspending a user's account
|
17
|
+
|
18
|
+
I would much rather delegate these features to an OpenID/Oauth service,
|
19
|
+
In other words, let a user authenticate to a third party that we both trust
|
20
|
+
(at least for the purpose we're using them for here)
|
21
|
+
such as Yahoo or Facebook or Google
|
22
|
+
who will then present a token to my client's site representing that the user has been authenticated.
|
23
|
+
|
24
|
+
Nevertheless, many of my clients and prospective clients have insisted that
|
25
|
+
their sites manage these features without requiring their customers to authenticate through a third party.
|
26
|
+
|
27
|
+
So I'm left again reinventing the same old authentication and account-management features every time.
|
28
|
+
The pages look different and the details may be slightly different each time
|
29
|
+
- some sites want to know their subscribers' full name, home address and phone number,
|
30
|
+
others just want an e-mail -
|
31
|
+
but the features and use-cases are nearly identical.
|
32
|
+
|
33
|
+
## Description
|
34
|
+
*accounts* is a website plug-in that offers than the basic user-account management
|
35
|
+
and authentication features that many sites need.
|
36
|
+
|
37
|
+
Accounts::Server defines the following paths for your web-app:
|
38
|
+
|
39
|
+
* POST '/logon'
|
40
|
+
* POST '/register'
|
41
|
+
* POST '/forgot-password'
|
42
|
+
* POST '/change-password'
|
43
|
+
* POST '/change-email'
|
44
|
+
|
45
|
+
Your app must provide the pages and forms that will post to these paths.
|
46
|
+
See demo/web_app.rb for example of usage.
|
47
|
+
That file could be your template for a new web-app that uses the accounts gem.
|
48
|
+
|
49
|
+
*accounts* supports a very lean and minimal user-registration protocol.
|
50
|
+
|
51
|
+
1. A user who wants to register need only submit a valid e-mail address.
|
52
|
+
1. The service will attempt to e-mail a unique URI to the address they have given.
|
53
|
+
1. When the new registree candidate visits that URI (presumably by clicking),
|
54
|
+
that e-mail (and their identity) may be considered as valid.
|
55
|
+
1. The new registree is then invited to create and verify a password.
|
56
|
+
|
57
|
+
This and other use cases are described in the Cucumber *features* documents and behavioral tests.
|
58
|
+
|
59
|
+
*accounts* makes a few assumptions:
|
60
|
+
|
61
|
+
1. Each subscriber to a site can be uniquely identified by whatever e-mail address he submits.
|
62
|
+
1. Password privacy depends on the transport layer (SSL).
|
63
|
+
1. Personal contact info and other attributes of a subscriber
|
64
|
+
are kept in a separate resource than Account that can be joined with Account.
|
65
|
+
1. Users may change their e-mail address, thus changing their primary identity.
|
66
|
+
This is justified because people do change their e-mail address from time to time
|
67
|
+
and should not have to re-register with a new identity.
|
68
|
+
Changing their e-mail will not break associations to other tables you have defined through *account_id*.
|
69
|
+
|
70
|
+
## Usage
|
71
|
+
See lib/accounts/configure.rb for list of configurable options
|
72
|
+
and for example of how to set them in order to customize
|
73
|
+
the pages and e-mails for your app.
|
74
|
+
|
75
|
+
Accounts defines several tables for keeping track of user accounts.
|
76
|
+
These do not include any personal or contact info other than a person's e-mail address.
|
77
|
+
If your app needs to maintain other info about it's subscribers,
|
78
|
+
you can create a separate table and join it with Accounts::Account defined in lib/accounts/model.rb
|
79
|
+
in a one-to-one relationship.
|
80
|
+
|
81
|
+
Accounts is agnostic about what templating engine engine your app uses,
|
82
|
+
as it does not use one itself,
|
83
|
+
but merely outputs shorts strings as responses that you may customize
|
84
|
+
by replacing them with your own strings or with Procs that use a template engine.
|
85
|
+
|
86
|
+
Accounts is agnostic about what mail engine engine your app uses,
|
87
|
+
although the default configuration uses http://github.com/mikel/mail.
|
88
|
+
If you wish to use a different mail engine,
|
89
|
+
you may do so in the Proc objects you provide to Accounts::configure.
|
90
|
+
|
91
|
+
## Status
|
92
|
+
Can't get sinatra-reloader to work since I converted it into a modular app.
|
93
|
+
|
94
|
+
Need to convert this into a proper Gem.
|
95
|
+
|
96
|
+
## Disclaimer
|
97
|
+
|
98
|
+
This package and all its contents are provided provided AS-IS, for demonstration purposes.
|
99
|
+
Lawrence Siden and Westside Consulting LLC
|
100
|
+
make no warranty about this package's security, correctness or fitness for commercial use.
|
101
|
+
|
102
|
+
## License
|
103
|
+
* Copyright <a href="http://westside-consulting.com/">Westside Consulting LLC</a>, Ann Arbor, MI, USA, 2012
|
104
|
+
* <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" property="dct:title" rel="dct:type">accounts</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="http://westside-consulting.com/" property="cc:attributionName" rel="cc:attributionURL">Lawrence Siden</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://github.com/lsiden" rel="dct:source">github.com</a>.
|
105
|
+
* [Ruby License](http://www.ruby-lang.org/en/LICENSE.txt)
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
|
5
|
+
#=begin
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'cucumber/rake/task'
|
8
|
+
|
9
|
+
# see http://autotestgroup.com/en/blog/80.html
|
10
|
+
|
11
|
+
desc "Run RSpec"
|
12
|
+
RSpec::Core::RakeTask.new(:rspec) do |t|
|
13
|
+
t.ruby_opts = %w[-w]
|
14
|
+
t.ruby_opts << ENV["opts"] if ENV["opts"]
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run Cucumber"
|
18
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
19
|
+
tag = ENV["tag"].split(',').map {|t| "@#{t}" }.join(',') if ENV["tag"]
|
20
|
+
t.cucumber_opts = "--format pretty"
|
21
|
+
t.cucumber_opts += %W[-t #{tag}] if tag
|
22
|
+
#STDERR.puts t.cucumber_opts.inspect
|
23
|
+
end
|
24
|
+
#=end
|
data/accounts.gemspec
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "accounts/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "accounts"
|
7
|
+
s.version = Accounts::Gem::VERSION
|
8
|
+
s.authors = ["Larry Siden, Westside Consulting LLC"]
|
9
|
+
s.email = ["lsiden@westside-consulting.com"]
|
10
|
+
s.homepage = "https://github.com/lsiden/accounts"
|
11
|
+
s.summary = %q{
|
12
|
+
*accounts* is a website plug-in that offers than the basic user-account management
|
13
|
+
and authentication features that many sites need.
|
14
|
+
}
|
15
|
+
s.description = %q{
|
16
|
+
Accounts::Server defines the following paths for your web-app:
|
17
|
+
|
18
|
+
* POST '/logon'
|
19
|
+
* POST '/register'
|
20
|
+
* POST '/forgot-password'
|
21
|
+
* POST '/change-password'
|
22
|
+
* POST '/change-email'
|
23
|
+
|
24
|
+
Your app must provide the pages and forms that will post to these paths.
|
25
|
+
}
|
26
|
+
|
27
|
+
s.rubyforge_project = "accounts"
|
28
|
+
|
29
|
+
s.files = `git ls-files`.split("\n")
|
30
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
31
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
32
|
+
s.require_paths = ["lib"]
|
33
|
+
|
34
|
+
s.add_development_dependency 'capybara'
|
35
|
+
s.add_development_dependency 'cucumber'
|
36
|
+
s.add_development_dependency 'rspec'
|
37
|
+
s.add_development_dependency 'rdoc'
|
38
|
+
s.add_development_dependency 'sinatra-contrib'
|
39
|
+
s.add_development_dependency 'mail-store-agent'
|
40
|
+
s.add_development_dependency 'mail-single_file_delivery'
|
41
|
+
s.add_development_dependency 'haml'
|
42
|
+
|
43
|
+
s.add_runtime_dependency 'rack', "~>1.3.6" # https://github.com/rack/rack/issues/299
|
44
|
+
s.add_runtime_dependency 'sinatra'
|
45
|
+
s.add_runtime_dependency 'thin'
|
46
|
+
s.add_runtime_dependency 'data_mapper'
|
47
|
+
s.add_runtime_dependency 'dm-types'
|
48
|
+
s.add_runtime_dependency 'dm-timestamps'
|
49
|
+
s.add_runtime_dependency 'dm-postgres-adapter'
|
50
|
+
s.add_runtime_dependency 'mail'
|
51
|
+
s.add_runtime_dependency 'logger'
|
52
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
!!!
|
2
|
+
%html{html_attrs}
|
3
|
+
/ Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
|
4
|
+
|
5
|
+
%body
|
6
|
+
|
7
|
+
%h1 Change E-mail
|
8
|
+
|
9
|
+
%form.change_email{:action => '/change-email', :method => 'post'}
|
10
|
+
.label_input
|
11
|
+
%label{:for=>"email"} New e-mail
|
12
|
+
%input{:name=>"email", :id=>"email", :type=>"text"}
|
13
|
+
.button
|
14
|
+
%button{:type => "submit"} Submit
|
@@ -0,0 +1,36 @@
|
|
1
|
+
!!!
|
2
|
+
%html{html_attrs}
|
3
|
+
/ Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
|
4
|
+
|
5
|
+
%head
|
6
|
+
:javascript
|
7
|
+
function validate(form) {
|
8
|
+
|
9
|
+
if (form.password.value != form.password2.value) {
|
10
|
+
alert("Passwords must match");
|
11
|
+
return false;
|
12
|
+
}
|
13
|
+
|
14
|
+
if (form.password.value.length < 8) {
|
15
|
+
alert("Password must have at least 8 characters");
|
16
|
+
return false;
|
17
|
+
}
|
18
|
+
return true;
|
19
|
+
}
|
20
|
+
|
21
|
+
%body
|
22
|
+
|
23
|
+
%h1 Change Password
|
24
|
+
|
25
|
+
%form#change_password_form{ :action => '/change-password',
|
26
|
+
:method => 'post',
|
27
|
+
:onsubmit => 'return validate(this)',
|
28
|
+
}
|
29
|
+
.label_input
|
30
|
+
%label{:for=>"password"} New Password
|
31
|
+
%input{:name=>"password", :id=>"password", :type=>"password"}
|
32
|
+
.label_input
|
33
|
+
%label{:for=>"password"} Confirm New Password
|
34
|
+
%input{:id=>"password2", :type=>"password"}
|
35
|
+
.button
|
36
|
+
%button{:type => "submit"} Submit
|