authentication-zero 2.8.3 → 2.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +6 -0
- data/authentication-zero-api.md +210 -0
- data/lib/authentication_zero/version.rb +1 -1
- data/lib/generators/authentication/authentication_generator.rb +52 -20
- data/lib/generators/authentication/templates/controllers/api/authentications/events_controller.rb.tt +5 -0
- data/lib/generators/authentication/templates/controllers/api/sessions_controller.rb.tt +1 -5
- data/lib/generators/authentication/templates/controllers/html/authentications/events_controller.rb.tt +5 -0
- data/lib/generators/authentication/templates/controllers/html/registrations_controller.rb.tt +1 -5
- data/lib/generators/authentication/templates/controllers/{omniauth_controller.rb.tt → html/sessions/omniauth_controller.rb.tt} +1 -5
- data/lib/generators/authentication/templates/controllers/html/sessions/sudos_controller.rb.tt +1 -1
- data/lib/generators/authentication/templates/controllers/html/sessions_controller.rb.tt +1 -5
- data/lib/generators/authentication/templates/erb/authentications/events/index.html.erb +33 -0
- data/lib/generators/authentication/templates/erb/sessions/new.html.erb.tt +1 -1
- data/lib/generators/authentication/templates/migrations/create_events_migration.rb.tt +12 -0
- data/lib/generators/authentication/templates/migrations/create_sessions_migration.rb.tt +2 -2
- data/lib/generators/authentication/templates/migrations/create_table_migration.rb.tt +7 -0
- data/lib/generators/authentication/templates/models/current.rb.tt +1 -0
- data/lib/generators/authentication/templates/models/event.rb.tt +8 -0
- data/lib/generators/authentication/templates/models/model.rb.tt +16 -4
- data/lib/generators/authentication/templates/models/session.rb.tt +15 -0
- data/lib/generators/authentication/templates/test_unit/controllers/api/identity/email_verifications_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/api/identity/emails_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/api/passwords_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/api/sessions/sudos_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/api/sessions_controller_test.rb.tt +3 -3
- data/lib/generators/authentication/templates/test_unit/controllers/html/identity/email_verifications_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/html/identity/emails_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/html/passwords_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/html/registrations_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/html/sessions/sudos_controller_test.rb.tt +1 -1
- data/lib/generators/authentication/templates/test_unit/controllers/html/sessions_controller_test.rb.tt +3 -3
- metadata +9 -4
- data/lib/generators/authentication/templates/migrations/add_omniauth_migration.rb.tt +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 349df436a5358765a5f4537e5e37e79c566dfe575875f77380fe1a2eeb21096f
|
4
|
+
data.tar.gz: f017571edaa6c887bcdecf4ffa023cc7d86830e0fba4ba3c7ad6dbd8626bf952
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a70ba5553accd5f23b71ad58b58dd270f78636b28bca944decb062d16a31d83808a9dca86cd2b38f5f83317a6748c32ef25d3944613686ea215c05cdcc647dbe
|
7
|
+
data.tar.gz: 2506decfeaa1e126d0160d11d787577ecff6c8afa6b4a27930a01ac65b9cfca2fa7ccdc82392dc488dafee102ebe4419ce1422450400810efcf7437fe1578454
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -20,7 +20,9 @@ The purpose of authentication zero is to generate a pre-built authentication sys
|
|
20
20
|
- Send e-mail confirmation when your email has been changed
|
21
21
|
- Send e-mail notification when someone has logged into your account
|
22
22
|
- Manage multiple sessions & devices
|
23
|
+
- Activity log (--trackable)
|
23
24
|
- Log out
|
25
|
+
- [API documentation](https://github.com/lazaronixon/authentication-zero/blob/master/authentication-zero-api.md)
|
24
26
|
|
25
27
|
## Security and best practices
|
26
28
|
|
@@ -73,6 +75,10 @@ Add these lines to your `app/views/home/index.html.erb`:
|
|
73
75
|
<%= link_to "Devices & Sessions", sessions_path %>
|
74
76
|
</div>
|
75
77
|
|
78
|
+
<div>
|
79
|
+
<%# link_to "Activity Log", authentications_events_path %>
|
80
|
+
</div>
|
81
|
+
|
76
82
|
<br>
|
77
83
|
|
78
84
|
<%= button_to "Log out", Current.session, method: :delete %>
|
@@ -0,0 +1,210 @@
|
|
1
|
+
# Authentication Zero API
|
2
|
+
|
3
|
+
This document describe the api endpoints available in authentication-zero.
|
4
|
+
|
5
|
+
## Making a request
|
6
|
+
|
7
|
+
To make a sign in request for example, append sign_in to the base URL to form something like http://localhost:3000/sign_in, also notice you have to include the Content-Type header and the JSON data: In cURL, it looks like this:
|
8
|
+
|
9
|
+
``` shell
|
10
|
+
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
|
11
|
+
-H 'Content-Type: application/json' \
|
12
|
+
-H 'User-Agent: MyApp (yourname@example.com)' \
|
13
|
+
-d '{ "email": "lazaronixon@hotmail.com", "password": "secret", "password_confirmation": "secret" }' \
|
14
|
+
http://localhost:3000/sign_in
|
15
|
+
```
|
16
|
+
|
17
|
+
## API endpoints
|
18
|
+
|
19
|
+
- [Sign up](#sign-up)
|
20
|
+
- [Sign in](#sign-in)
|
21
|
+
- [Get your sessions](#get-your-sessions)
|
22
|
+
- [Get a session](#get-a-session)
|
23
|
+
- [Destroy a session](#destroy-a-session)
|
24
|
+
- [Execute sudo](#execute-sudo)
|
25
|
+
- [Update your password](#update-your-password)
|
26
|
+
- [Update your email](#update-your-email)
|
27
|
+
- [Send verification email](#send-verification-email)
|
28
|
+
- [Verify email](#verify-email)
|
29
|
+
- [Send password reset email](#send-password-reset-email)
|
30
|
+
- [Reset password](#reset-password)
|
31
|
+
|
32
|
+
## Registrations
|
33
|
+
|
34
|
+
### Sign up
|
35
|
+
|
36
|
+
* `POST /sign_up` creates a user on database.
|
37
|
+
|
38
|
+
###### Example JSON Request
|
39
|
+
|
40
|
+
``` json
|
41
|
+
{
|
42
|
+
"email": "lazaronixon@hotmail.com",
|
43
|
+
"password": "Secret1*2*3*4*5*6",
|
44
|
+
"password_confirmation": "Secret1*2*3*4*5*6"
|
45
|
+
}
|
46
|
+
```
|
47
|
+
|
48
|
+
This endpoint will return `201 Created` with the current JSON representation of the user if the creation was a success.
|
49
|
+
|
50
|
+
## Sessions
|
51
|
+
|
52
|
+
### Sign in
|
53
|
+
|
54
|
+
* `POST /sign_in` creates a session on database.
|
55
|
+
|
56
|
+
###### Example JSON Request
|
57
|
+
|
58
|
+
``` json
|
59
|
+
{
|
60
|
+
"email": "lazaronixon@hotmail.com",
|
61
|
+
"password": "Secret1*2*3*4*5*6"
|
62
|
+
}
|
63
|
+
```
|
64
|
+
|
65
|
+
This endpoint will return `201 Created` with the current JSON representation of the session if the creation was a success, also you will receive a `X-Session-Token` that you will use as your authorization token.
|
66
|
+
|
67
|
+
|
68
|
+
### Get your sessions
|
69
|
+
|
70
|
+
* `GET /sessions` will return a list of sessions.
|
71
|
+
|
72
|
+
###### Example JSON Response
|
73
|
+
|
74
|
+
``` json
|
75
|
+
[
|
76
|
+
{
|
77
|
+
"id": 2,
|
78
|
+
"user_id": 1,
|
79
|
+
"user_agent": "insomnia/2022.1.0",
|
80
|
+
"ip_address": "127.0.0.1",
|
81
|
+
"sudo_at": "2022-03-04T17:20:33.632Z",
|
82
|
+
"created_at": "2022-03-04T17:20:33.632Z",
|
83
|
+
"updated_at": "2022-03-04T17:20:33.632Z"
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"id": 1,
|
87
|
+
"user_id": 1,
|
88
|
+
"user_agent": "insomnia/2022.1.0",
|
89
|
+
"ip_address": "127.0.0.1",
|
90
|
+
"sudo_at": "2022-03-04T17:14:03.386Z",
|
91
|
+
"created_at": "2022-03-04T17:14:03.386Z",
|
92
|
+
"updated_at": "2022-03-04T17:14:03.386Z"
|
93
|
+
}
|
94
|
+
]
|
95
|
+
```
|
96
|
+
|
97
|
+
### Get a session
|
98
|
+
|
99
|
+
* `GET /sessions/1` will return the session with an ID of 1.
|
100
|
+
|
101
|
+
###### Example JSON Response
|
102
|
+
|
103
|
+
``` json
|
104
|
+
{
|
105
|
+
"id": 1,
|
106
|
+
"user_id": 1,
|
107
|
+
"user_agent": "insomnia/2022.1.0",
|
108
|
+
"ip_address": "127.0.0.1",
|
109
|
+
"sudo_at": "2022-03-04T17:14:03.386Z",
|
110
|
+
"created_at": "2022-03-04T17:14:03.386Z",
|
111
|
+
"updated_at": "2022-03-04T17:14:03.386Z"
|
112
|
+
}
|
113
|
+
```
|
114
|
+
|
115
|
+
### Destroy a session
|
116
|
+
|
117
|
+
* `DELETE /sessions/1` will destroy the session with an ID of 1.
|
118
|
+
|
119
|
+
Returns `204 No Content` if successful.
|
120
|
+
|
121
|
+
|
122
|
+
### Execute sudo
|
123
|
+
|
124
|
+
* `POST /sessions/sudo` will grant temporary access to sensitive information.
|
125
|
+
|
126
|
+
###### Example JSON Request
|
127
|
+
|
128
|
+
``` json
|
129
|
+
{
|
130
|
+
"password": "Secret1*2*3*4*5*6",
|
131
|
+
}
|
132
|
+
```
|
133
|
+
|
134
|
+
Returns `204 No Content` if successful.
|
135
|
+
|
136
|
+
## Password
|
137
|
+
|
138
|
+
### Update your password
|
139
|
+
|
140
|
+
* `PUT /password` allows changing your password.
|
141
|
+
|
142
|
+
###### Example JSON Request
|
143
|
+
|
144
|
+
``` json
|
145
|
+
{
|
146
|
+
"current_password": "Secret1*2*3*4*5*6",
|
147
|
+
"password": "NewPassword12$34$56$7",
|
148
|
+
"password_confirmation": "NewPassword12$34$56$7"
|
149
|
+
}
|
150
|
+
```
|
151
|
+
|
152
|
+
This endpoint will return 200 OK with the current JSON representation of the user if the update was a success.
|
153
|
+
|
154
|
+
## Email
|
155
|
+
|
156
|
+
### Update your email
|
157
|
+
|
158
|
+
* `PUT /identity/email` allows changing your email. **(requires sudo)**.
|
159
|
+
|
160
|
+
###### Example JSON Request
|
161
|
+
|
162
|
+
``` json
|
163
|
+
{
|
164
|
+
"email": "new_email@hey.com"
|
165
|
+
}
|
166
|
+
```
|
167
|
+
|
168
|
+
This endpoint will return 200 OK with the current JSON representation of the user if the update was a success.
|
169
|
+
|
170
|
+
## Email verification
|
171
|
+
|
172
|
+
### Send verification email
|
173
|
+
|
174
|
+
* `POST /identity/email_verification` sends an email verification with the instructions and link to proceed with the verification.
|
175
|
+
|
176
|
+
Returns `204 No Content` if successful.
|
177
|
+
|
178
|
+
### Verify email
|
179
|
+
|
180
|
+
* `GET /identity/email_verification` verify your email using a temporary token.
|
181
|
+
|
182
|
+
**Required parameters:** `email` and `token`.
|
183
|
+
|
184
|
+
Example: `/identity/email_verification?email=lazaronixon@hotmail.com&token=eyJfcmFpbHMiOnsibWVzc2FnZSI6Ik1nPT0iLCJleHAiOm51bGwsInB1ciI6InNlc3Npb24ifX0=--1a277b4a5576c6e371144a22476979a18d3e45fb8515a79e815cd4b95eb5fb6b`
|
185
|
+
|
186
|
+
Returns `204 No Content` if successful.
|
187
|
+
|
188
|
+
## Password reset
|
189
|
+
|
190
|
+
### Send password reset email
|
191
|
+
|
192
|
+
* `POST /identity/password_reset` sends a password reset email with the instructions and link to proceed reset.
|
193
|
+
|
194
|
+
Returns `204 No Content` if successful.
|
195
|
+
|
196
|
+
### Reset password
|
197
|
+
|
198
|
+
* `PUT /identity/password_reset` allows changing your password through a email token.
|
199
|
+
|
200
|
+
##### Example JSON Request
|
201
|
+
|
202
|
+
``` json
|
203
|
+
{
|
204
|
+
"password": "NewPassword12$34$56$7",
|
205
|
+
"password_confirmation": "NewPassword12$34$56$7",
|
206
|
+
"token": "eyJfcmFpbHMiOnsibWVzc2FnZSI6Ik1nPT0iLCJleHAiOm51bGwsInB1ciI6InNlc3Npb24ifX0=--1a277b4a5576c6e371144a22476979a18d3e45fb8515a79e815cd4b95eb5fb6b",
|
207
|
+
}
|
208
|
+
```
|
209
|
+
|
210
|
+
This endpoint will return 200 OK with the current JSON representation of the user if the update was a success.
|
@@ -8,6 +8,7 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
|
|
8
8
|
class_option :lockable, type: :boolean, desc: "Add password reset locking"
|
9
9
|
class_option :ratelimit, type: :boolean, desc: "Add request rate limiting"
|
10
10
|
class_option :omniauthable, type: :boolean, desc: "Add social login support"
|
11
|
+
class_option :trackable, type: :boolean, desc: "Add activity log support"
|
11
12
|
|
12
13
|
source_root File.expand_path("templates", __dir__)
|
13
14
|
|
@@ -47,7 +48,7 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
|
|
47
48
|
def create_migrations
|
48
49
|
migration_template "migrations/create_table_migration.rb", "#{db_migrate_path}/create_#{table_name}.rb"
|
49
50
|
migration_template "migrations/create_sessions_migration.rb", "#{db_migrate_path}/create_sessions.rb"
|
50
|
-
migration_template "migrations/
|
51
|
+
migration_template "migrations/create_events_migration.rb", "#{db_migrate_path}/create_events.rb" if options.trackable?
|
51
52
|
end
|
52
53
|
|
53
54
|
def create_models
|
@@ -55,6 +56,7 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
|
|
55
56
|
template "models/session.rb", "app/models/session.rb"
|
56
57
|
template "models/current.rb", "app/models/current.rb"
|
57
58
|
template "models/locking.rb", "app/models/locking.rb" if options.lockable?
|
59
|
+
template "models/event.rb", "app/models/event.rb" if options.trackable?
|
58
60
|
end
|
59
61
|
|
60
62
|
def create_fixture_file
|
@@ -65,39 +67,53 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
|
|
65
67
|
api_code = <<~CODE
|
66
68
|
include ActionController::HttpAuthentication::Token::ControllerMethods
|
67
69
|
|
70
|
+
before_action :set_current_request_details
|
68
71
|
before_action :authenticate
|
69
72
|
|
70
|
-
def authenticate
|
71
|
-
if session = authenticate_with_http_token { |token, _| Session.find_signed(token) }
|
72
|
-
Current.session = session
|
73
|
-
else
|
74
|
-
request_http_token_authentication
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
73
|
def require_sudo
|
79
74
|
if Current.session.sudo_at < 30.minutes.ago
|
80
75
|
render json: { error: "Enter your password to continue" }, status: :forbidden
|
81
76
|
end
|
82
77
|
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def authenticate
|
81
|
+
if session = authenticate_with_http_token { |token, _| Session.find_signed(token) }
|
82
|
+
Current.session = session
|
83
|
+
else
|
84
|
+
request_http_token_authentication
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_current_request_details
|
89
|
+
Current.user_agent = request.user_agent
|
90
|
+
Current.ip_address = request.ip
|
91
|
+
end
|
83
92
|
CODE
|
84
93
|
|
85
94
|
html_code = <<~CODE
|
95
|
+
before_action :set_current_request_details
|
86
96
|
before_action :authenticate
|
87
97
|
|
88
|
-
def authenticate
|
89
|
-
if session = Session.find_by_id(cookies.signed[:session_token])
|
90
|
-
Current.session = session
|
91
|
-
else
|
92
|
-
redirect_to sign_in_path
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
98
|
def require_sudo
|
97
99
|
if Current.session.sudo_at < 30.minutes.ago
|
98
100
|
redirect_to new_sessions_sudo_path(proceed_to_url: request.url)
|
99
101
|
end
|
100
102
|
end
|
103
|
+
|
104
|
+
private
|
105
|
+
def authenticate
|
106
|
+
if session = Session.find_by_id(cookies.signed[:session_token])
|
107
|
+
Current.session = session
|
108
|
+
else
|
109
|
+
redirect_to sign_in_path
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def set_current_request_details
|
114
|
+
Current.user_agent = request.user_agent
|
115
|
+
Current.ip_address = request.ip
|
116
|
+
end
|
101
117
|
CODE
|
102
118
|
|
103
119
|
inject_code = options.api? ? api_code : html_code
|
@@ -105,8 +121,13 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
|
|
105
121
|
end
|
106
122
|
|
107
123
|
def create_controllers
|
108
|
-
directory "controllers/#{format_folder}", "app/controllers"
|
109
|
-
template "controllers/
|
124
|
+
directory "controllers/#{format_folder}/identity", "app/controllers/identity"
|
125
|
+
template "controllers/#{format_folder}/passwords_controller.rb", "app/controllers/passwords_controller.rb"
|
126
|
+
template "controllers/#{format_folder}/registrations_controller.rb", "app/controllers/registrations_controller.rb"
|
127
|
+
template "controllers/#{format_folder}/sessions_controller.rb", "app/controllers/sessions_controller.rb"
|
128
|
+
template "controllers/#{format_folder}/sessions/sudos_controller.rb", "app/controllers/sessions/sudos_controller.rb"
|
129
|
+
template "controllers/#{format_folder}/sessions/omniauth_controller.rb", "app/controllers/sessions/omniauth_controller.rb" if omniauthable?
|
130
|
+
template "controllers/#{format_folder}/authentications/events_controller.rb", "app/controllers/authentications/events_controller.rb" if options.trackable?
|
110
131
|
end
|
111
132
|
|
112
133
|
def create_views
|
@@ -114,7 +135,14 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
|
|
114
135
|
directory "erb/identity_mailer", "app/views/identity_mailer"
|
115
136
|
directory "erb/session_mailer", "app/views/session_mailer"
|
116
137
|
else
|
117
|
-
directory "erb", "app/views"
|
138
|
+
directory "erb/identity_mailer", "app/views/identity_mailer"
|
139
|
+
directory "erb/session_mailer", "app/views/session_mailer"
|
140
|
+
|
141
|
+
directory "erb/identity", "app/views/identity"
|
142
|
+
directory "erb/passwords", "app/views/passwords"
|
143
|
+
directory "erb/registrations", "app/views/registrations"
|
144
|
+
directory "erb/sessions", "app/views/sessions"
|
145
|
+
directory "erb/authentications/events", "app/views/authentications/events" if options.trackable?
|
118
146
|
end
|
119
147
|
end
|
120
148
|
|
@@ -129,6 +157,10 @@ class AuthenticationGenerator < Rails::Generators::NamedBase
|
|
129
157
|
route "get '/auth/failure', to: 'sessions/omniauth#failure'"
|
130
158
|
end
|
131
159
|
|
160
|
+
if options.trackable?
|
161
|
+
route "resources :events, only: :index", namespace: :authentications
|
162
|
+
end
|
163
|
+
|
132
164
|
route "resource :password_reset, only: [:new, :edit, :create, :update]", namespace: :identity
|
133
165
|
route "resource :email_verification, only: [:edit, :create]", namespace: :identity
|
134
166
|
route "resource :email, only: [:edit, :update]", namespace: :identity
|
@@ -15,7 +15,7 @@ class SessionsController < ApplicationController
|
|
15
15
|
<%= singular_table_name %> = <%= class_name %>.find_by(email: params[:email])
|
16
16
|
|
17
17
|
if <%= singular_table_name %> && <%= singular_table_name %>.authenticate(params[:password])
|
18
|
-
@session = <%= singular_table_name %>.sessions.create!
|
18
|
+
@session = <%= singular_table_name %>.sessions.create!
|
19
19
|
response.set_header("X-Session-Token", @session.signed_id)
|
20
20
|
|
21
21
|
render json: @session, status: :created
|
@@ -32,8 +32,4 @@ class SessionsController < ApplicationController
|
|
32
32
|
def set_session
|
33
33
|
@session = Current.<%= singular_table_name %>.sessions.find(params[:id])
|
34
34
|
end
|
35
|
-
|
36
|
-
def session_params
|
37
|
-
{ user_agent: request.user_agent, ip_address: request.remote_ip, sudo_at: Time.current }
|
38
|
-
end
|
39
35
|
end
|
data/lib/generators/authentication/templates/controllers/html/registrations_controller.rb.tt
CHANGED
@@ -9,7 +9,7 @@ class RegistrationsController < ApplicationController
|
|
9
9
|
@<%= singular_table_name %> = <%= class_name %>.new(<%= "#{singular_table_name}_params" %>)
|
10
10
|
|
11
11
|
if @<%= singular_table_name %>.save
|
12
|
-
session = @<%= singular_table_name %>.sessions.create!
|
12
|
+
session = @<%= singular_table_name %>.sessions.create!
|
13
13
|
cookies.signed.permanent[:session_token] = { value: session.id, httponly: true }
|
14
14
|
|
15
15
|
redirect_to root_path, notice: "Welcome! You have signed up successfully"
|
@@ -22,8 +22,4 @@ class RegistrationsController < ApplicationController
|
|
22
22
|
def <%= "#{singular_table_name}_params" %>
|
23
23
|
params.permit(:email, :password, :password_confirmation)
|
24
24
|
end
|
25
|
-
|
26
|
-
def session_params
|
27
|
-
{ user_agent: request.user_agent, ip_address: request.remote_ip, sudo_at: Time.current }
|
28
|
-
end
|
29
25
|
end
|
@@ -6,7 +6,7 @@ class Sessions::OmniauthController < ApplicationController
|
|
6
6
|
@<%= singular_table_name %> = <%= class_name %>.where(omniauth_params).first_or_initialize(<%= "#{singular_table_name}_params" %>)
|
7
7
|
|
8
8
|
if @<%= singular_table_name %>.save
|
9
|
-
session = @<%= singular_table_name %>.sessions.create!
|
9
|
+
session = @<%= singular_table_name %>.sessions.create!
|
10
10
|
cookies.signed.permanent[:session_token] = { value: session.id, httponly: true }
|
11
11
|
|
12
12
|
redirect_to root_path, notice: "Signed in successfully"
|
@@ -28,10 +28,6 @@ class Sessions::OmniauthController < ApplicationController
|
|
28
28
|
{ email: omniauth.info.email, password: SecureRandom::base58, verified: true }
|
29
29
|
end
|
30
30
|
|
31
|
-
def session_params
|
32
|
-
{ user_agent: request.user_agent, ip_address: request.remote_ip, sudo_at: Time.current }
|
33
|
-
end
|
34
|
-
|
35
31
|
def omniauth
|
36
32
|
request.env["omniauth.auth"]
|
37
33
|
end
|
data/lib/generators/authentication/templates/controllers/html/sessions/sudos_controller.rb.tt
CHANGED
@@ -5,7 +5,7 @@ class Sessions::SudosController < ApplicationController
|
|
5
5
|
def create
|
6
6
|
session = Current.session
|
7
7
|
|
8
|
-
<% if
|
8
|
+
<% if omniauthable? -%>
|
9
9
|
if session.<%= singular_table_name %>.authenticate(params[:password]) || session.<%= singular_table_name %>.provider
|
10
10
|
<% else -%>
|
11
11
|
if session.<%= singular_table_name %>.authenticate(params[:password])
|
@@ -15,7 +15,7 @@ class SessionsController < ApplicationController
|
|
15
15
|
<%= singular_table_name %> = <%= class_name %>.find_by(email: params[:email])
|
16
16
|
|
17
17
|
if <%= singular_table_name %> && <%= singular_table_name %>.authenticate(params[:password])
|
18
|
-
@session = <%= singular_table_name %>.sessions.create!
|
18
|
+
@session = <%= singular_table_name %>.sessions.create!
|
19
19
|
cookies.signed.permanent[:session_token] = { value: @session.id, httponly: true }
|
20
20
|
|
21
21
|
redirect_to root_path, notice: "Signed in successfully"
|
@@ -32,8 +32,4 @@ class SessionsController < ApplicationController
|
|
32
32
|
def set_session
|
33
33
|
@session = Current.<%= singular_table_name %>.sessions.find(params[:id])
|
34
34
|
end
|
35
|
-
|
36
|
-
def session_params
|
37
|
-
{ user_agent: request.user_agent, ip_address: request.remote_ip, sudo_at: Time.current }
|
38
|
-
end
|
39
35
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<h1>Activity Log</h1>
|
2
|
+
|
3
|
+
<div id="sessions">
|
4
|
+
<% @events.each do |event| %>
|
5
|
+
<div id="<%= dom_id event %>">
|
6
|
+
<p>
|
7
|
+
<strong>User Agent:</strong>
|
8
|
+
<%= event.user_agent %>
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
<strong>Action:</strong>
|
13
|
+
<%= event.action %>
|
14
|
+
</p>
|
15
|
+
|
16
|
+
<p>
|
17
|
+
<strong>Ip Address:</strong>
|
18
|
+
<%= event.ip_address %>
|
19
|
+
</p>
|
20
|
+
|
21
|
+
<p>
|
22
|
+
<strong>Created at:</strong>
|
23
|
+
<%= event.created_at %>
|
24
|
+
</p>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<br>
|
30
|
+
|
31
|
+
<div>
|
32
|
+
<%= link_to "Back", root_path %>
|
33
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
2
|
+
def change
|
3
|
+
create_table :events do |t|
|
4
|
+
t.references :<%= singular_table_name %>, null: false, foreign_key: true
|
5
|
+
t.string :action, null: false
|
6
|
+
t.string :user_agent
|
7
|
+
t.string :ip_address
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -3,8 +3,8 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
3
3
|
create_table :sessions do |t|
|
4
4
|
t.references :<%= singular_table_name %>, null: false, foreign_key: true
|
5
5
|
|
6
|
-
t.string :user_agent
|
7
|
-
t.string :ip_address
|
6
|
+
t.string :user_agent
|
7
|
+
t.string :ip_address
|
8
8
|
|
9
9
|
t.datetime :sudo_at, null: false
|
10
10
|
|
@@ -5,10 +5,17 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
|
|
5
5
|
t.string :password_digest, null: false
|
6
6
|
|
7
7
|
t.boolean :verified, null: false, default: false
|
8
|
+
<% if omniauthable? %>
|
9
|
+
t.string :provider
|
10
|
+
t.string :uid
|
11
|
+
<% end -%>
|
8
12
|
|
9
13
|
t.timestamps
|
10
14
|
end
|
11
15
|
|
12
16
|
add_index :<%= table_name %>, :email, unique: true
|
17
|
+
<% if omniauthable? -%>
|
18
|
+
add_index :<%= table_name %>, [:provider, :uid], unique: true
|
19
|
+
<% end -%>
|
13
20
|
end
|
14
21
|
end
|
@@ -2,6 +2,9 @@ class <%= class_name %> < ApplicationRecord
|
|
2
2
|
has_secure_password
|
3
3
|
|
4
4
|
has_many :sessions, dependent: :destroy
|
5
|
+
<% if options.trackable? -%>
|
6
|
+
has_many :events, dependent: :destroy
|
7
|
+
<% end -%>
|
5
8
|
|
6
9
|
validates :email, presence: true, uniqueness: true
|
7
10
|
validates_format_of :email, with: /\A[^@\s]+@[^@\s]+\z/
|
@@ -24,11 +27,20 @@ class <%= class_name %> < ApplicationRecord
|
|
24
27
|
sessions.where.not(id: Current.session).destroy_all
|
25
28
|
end
|
26
29
|
|
27
|
-
|
28
|
-
IdentityMailer.with(
|
30
|
+
after_save_commit if: :email_previously_changed? do
|
31
|
+
IdentityMailer.with(user: self).email_verify_confirmation.deliver_later
|
32
|
+
end
|
33
|
+
<% if options.trackable? %>
|
34
|
+
after_save_commit if: :email_previously_changed? do
|
35
|
+
events.create! action: "email_verification_requested"
|
36
|
+
end
|
37
|
+
|
38
|
+
after_update if: :password_digest_previously_changed? do
|
39
|
+
events.create! action: "password_changed"
|
29
40
|
end
|
30
41
|
|
31
|
-
|
32
|
-
|
42
|
+
after_update if: :verified_previously_changed? do
|
43
|
+
events.create! action: "email_verified" if verified?
|
33
44
|
end
|
45
|
+
<% end -%>
|
34
46
|
end
|
@@ -1,7 +1,22 @@
|
|
1
1
|
class Session < ApplicationRecord
|
2
2
|
belongs_to :<%= singular_table_name %>
|
3
3
|
|
4
|
+
before_create do
|
5
|
+
self.user_agent = Current.user_agent
|
6
|
+
self.ip_address = Current.ip_address
|
7
|
+
self.sudo_at = Time.current
|
8
|
+
end
|
9
|
+
|
4
10
|
after_create_commit do
|
5
11
|
SessionMailer.with(session: self).signed_in_notification.deliver_later
|
6
12
|
end
|
13
|
+
<% if options.trackable? %>
|
14
|
+
after_create do
|
15
|
+
<%= singular_table_name %>.events.create! action: "signed_in"
|
16
|
+
end
|
17
|
+
|
18
|
+
after_destroy do
|
19
|
+
<%= singular_table_name %>.events.create! action: "signed_out"
|
20
|
+
end
|
21
|
+
<% end -%>
|
7
22
|
end
|
@@ -39,6 +39,6 @@ class Identity::EmailVerificationsControllerTest < ActionDispatch::IntegrationTe
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def sign_in_as(<%= singular_table_name %>)
|
42
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
42
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); [<%= singular_table_name %>, response.headers["X-Session-Token"]]
|
43
43
|
end
|
44
44
|
end
|
@@ -20,6 +20,6 @@ class Identity::EmailsControllerTest < ActionDispatch::IntegrationTest
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def sign_in_as(<%= singular_table_name %>)
|
23
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
23
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); [<%= singular_table_name %>, response.headers["X-Session-Token"]]
|
24
24
|
end
|
25
25
|
end
|
@@ -18,6 +18,6 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def sign_in_as(<%= singular_table_name %>)
|
21
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
21
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); [<%= singular_table_name %>, response.headers["X-Session-Token"]]
|
22
22
|
end
|
23
23
|
end
|
@@ -19,6 +19,6 @@ class Sessions::SudosControllerTest < ActionDispatch::IntegrationTest
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def sign_in_as(<%= singular_table_name %>)
|
22
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
22
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); [<%= singular_table_name %>, response.headers["X-Session-Token"]]
|
23
23
|
end
|
24
24
|
end
|
@@ -16,14 +16,14 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
|
|
16
16
|
end
|
17
17
|
|
18
18
|
test "should sign in" do
|
19
|
-
post sign_in_url, params: { email: @<%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
19
|
+
post sign_in_url, params: { email: @<%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
20
20
|
|
21
21
|
assert_enqueued_email_with SessionMailer, :signed_in_notification, args: { session: @<%= singular_table_name %>.sessions.last }
|
22
22
|
assert_response :created
|
23
23
|
end
|
24
24
|
|
25
25
|
test "should not sign in with wrong credentials" do
|
26
|
-
post sign_in_url, params: { email: @<%= singular_table_name %>.email, password: "SecretWrong1*3" }
|
26
|
+
post sign_in_url, params: { email: @<%= singular_table_name %>.email, password: "SecretWrong1*3" }
|
27
27
|
assert_response :unauthorized
|
28
28
|
end
|
29
29
|
|
@@ -33,6 +33,6 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def sign_in_as(<%= singular_table_name %>)
|
36
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
36
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); [<%= singular_table_name %>, response.headers["X-Session-Token"]]
|
37
37
|
end
|
38
38
|
end
|
@@ -39,6 +39,6 @@ class Identity::EmailVerificationsControllerTest < ActionDispatch::IntegrationTe
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def sign_in_as(<%= singular_table_name %>)
|
42
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
42
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); <%= singular_table_name %>
|
43
43
|
end
|
44
44
|
end
|
@@ -30,6 +30,6 @@ class Identity::EmailsControllerTest < ActionDispatch::IntegrationTest
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def sign_in_as(<%= singular_table_name %>)
|
33
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
33
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); <%= singular_table_name %>
|
34
34
|
end
|
35
35
|
end
|
@@ -23,6 +23,6 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def sign_in_as(<%= singular_table_name %>)
|
26
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
26
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); <%= singular_table_name %>
|
27
27
|
end
|
28
28
|
end
|
@@ -8,7 +8,7 @@ class RegistrationsControllerTest < ActionDispatch::IntegrationTest
|
|
8
8
|
|
9
9
|
test "should sign up" do
|
10
10
|
assert_difference("<%= class_name %>.count") do
|
11
|
-
post sign_up_url, params: { email: "lazaronixon@hey.com", password: "Secret1*3*5*", password_confirmation: "Secret1*3*5*" }
|
11
|
+
post sign_up_url, params: { email: "lazaronixon@hey.com", password: "Secret1*3*5*", password_confirmation: "Secret1*3*5*" }
|
12
12
|
end
|
13
13
|
|
14
14
|
assert_redirected_to root_url
|
@@ -21,6 +21,6 @@ class Sessions::SudosControllerTest < ActionDispatch::IntegrationTest
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def sign_in_as(<%= singular_table_name %>)
|
24
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
24
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); [<%= singular_table_name %>, response.headers["X-Session-Token"]]
|
25
25
|
end
|
26
26
|
end
|
@@ -18,7 +18,7 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
|
|
18
18
|
end
|
19
19
|
|
20
20
|
test "should sign in" do
|
21
|
-
post sign_in_url, params: { email: @<%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
21
|
+
post sign_in_url, params: { email: @<%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
22
22
|
assert_enqueued_email_with SessionMailer, :signed_in_notification, args: { session: @<%= singular_table_name %>.sessions.last }
|
23
23
|
|
24
24
|
assert_redirected_to root_url
|
@@ -28,7 +28,7 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
|
|
28
28
|
end
|
29
29
|
|
30
30
|
test "should not sign in with wrong credentials" do
|
31
|
-
post sign_in_url, params: { email: @<%= singular_table_name %>.email, password: "SecretWrong1*3" }
|
31
|
+
post sign_in_url, params: { email: @<%= singular_table_name %>.email, password: "SecretWrong1*3" }
|
32
32
|
assert_redirected_to sign_in_url(email_hint: @<%= singular_table_name %>.email)
|
33
33
|
assert_equal "That email or password is incorrect", flash[:alert]
|
34
34
|
|
@@ -47,6 +47,6 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def sign_in_as(<%= singular_table_name %>)
|
50
|
-
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }
|
50
|
+
post(sign_in_url, params: { email: <%= singular_table_name %>.email, password: "Secret1*3*5*" }); <%= singular_table_name %>
|
51
51
|
end
|
52
52
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authentication-zero
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nixon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -26,6 +26,7 @@ files:
|
|
26
26
|
- LICENSE.txt
|
27
27
|
- README.md
|
28
28
|
- Rakefile
|
29
|
+
- authentication-zero-api.md
|
29
30
|
- authentication-zero.gemspec
|
30
31
|
- lib/authentication-zero.rb
|
31
32
|
- lib/authentication_zero.rb
|
@@ -34,6 +35,7 @@ files:
|
|
34
35
|
- lib/generators/authentication/authentication_generator.rb
|
35
36
|
- lib/generators/authentication/templates/config/initializers/omniauth.rb
|
36
37
|
- lib/generators/authentication/templates/config/redis/shared.yml
|
38
|
+
- lib/generators/authentication/templates/controllers/api/authentications/events_controller.rb.tt
|
37
39
|
- lib/generators/authentication/templates/controllers/api/identity/email_verifications_controller.rb.tt
|
38
40
|
- lib/generators/authentication/templates/controllers/api/identity/emails_controller.rb.tt
|
39
41
|
- lib/generators/authentication/templates/controllers/api/identity/password_resets_controller.rb.tt
|
@@ -41,14 +43,16 @@ files:
|
|
41
43
|
- lib/generators/authentication/templates/controllers/api/registrations_controller.rb.tt
|
42
44
|
- lib/generators/authentication/templates/controllers/api/sessions/sudos_controller.rb.tt
|
43
45
|
- lib/generators/authentication/templates/controllers/api/sessions_controller.rb.tt
|
46
|
+
- lib/generators/authentication/templates/controllers/html/authentications/events_controller.rb.tt
|
44
47
|
- lib/generators/authentication/templates/controllers/html/identity/email_verifications_controller.rb.tt
|
45
48
|
- lib/generators/authentication/templates/controllers/html/identity/emails_controller.rb.tt
|
46
49
|
- lib/generators/authentication/templates/controllers/html/identity/password_resets_controller.rb.tt
|
47
50
|
- lib/generators/authentication/templates/controllers/html/passwords_controller.rb.tt
|
48
51
|
- lib/generators/authentication/templates/controllers/html/registrations_controller.rb.tt
|
52
|
+
- lib/generators/authentication/templates/controllers/html/sessions/omniauth_controller.rb.tt
|
49
53
|
- lib/generators/authentication/templates/controllers/html/sessions/sudos_controller.rb.tt
|
50
54
|
- lib/generators/authentication/templates/controllers/html/sessions_controller.rb.tt
|
51
|
-
- lib/generators/authentication/templates/
|
55
|
+
- lib/generators/authentication/templates/erb/authentications/events/index.html.erb
|
52
56
|
- lib/generators/authentication/templates/erb/identity/emails/edit.html.erb.tt
|
53
57
|
- lib/generators/authentication/templates/erb/identity/password_resets/edit.html.erb.tt
|
54
58
|
- lib/generators/authentication/templates/erb/identity/password_resets/new.html.erb.tt
|
@@ -65,10 +69,11 @@ files:
|
|
65
69
|
- lib/generators/authentication/templates/erb/sessions/sudos/new.html.erb.tt
|
66
70
|
- lib/generators/authentication/templates/mailers/identity_mailer.rb.tt
|
67
71
|
- lib/generators/authentication/templates/mailers/session_mailer.rb.tt
|
68
|
-
- lib/generators/authentication/templates/migrations/
|
72
|
+
- lib/generators/authentication/templates/migrations/create_events_migration.rb.tt
|
69
73
|
- lib/generators/authentication/templates/migrations/create_sessions_migration.rb.tt
|
70
74
|
- lib/generators/authentication/templates/migrations/create_table_migration.rb.tt
|
71
75
|
- lib/generators/authentication/templates/models/current.rb.tt
|
76
|
+
- lib/generators/authentication/templates/models/event.rb.tt
|
72
77
|
- lib/generators/authentication/templates/models/locking.rb.tt
|
73
78
|
- lib/generators/authentication/templates/models/model.rb.tt
|
74
79
|
- lib/generators/authentication/templates/models/session.rb.tt
|
@@ -1,8 +0,0 @@
|
|
1
|
-
class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
2
|
-
def change
|
3
|
-
add_column :<%= table_name %>, :provider, :string
|
4
|
-
add_column :<%= table_name %>, :uid, :string
|
5
|
-
end
|
6
|
-
|
7
|
-
add_index :<%= table_name %>, [:provider, :uid], unique: true
|
8
|
-
end
|