@feathersjs/authentication 5.0.0-pre.22 → 5.0.0-pre.25
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.
- package/CHANGELOG.md +27 -0
- package/lib/core.d.ts +1 -0
- package/lib/core.js +5 -7
- package/lib/core.js.map +1 -1
- package/lib/hooks/authenticate.js +3 -2
- package/lib/hooks/authenticate.js.map +1 -1
- package/lib/hooks/connection.js.map +1 -1
- package/lib/hooks/event.js.map +1 -1
- package/lib/hooks/index.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/jwt.js +6 -4
- package/lib/jwt.js.map +1 -1
- package/lib/options.js +6 -3
- package/lib/options.js.map +1 -1
- package/lib/service.js +12 -8
- package/lib/service.js.map +1 -1
- package/lib/strategy.js.map +1 -1
- package/package.json +11 -11
- package/src/core.ts +107 -95
- package/src/hooks/authenticate.ts +35 -31
- package/src/hooks/connection.ts +12 -9
- package/src/hooks/event.ts +9 -9
- package/src/hooks/index.ts +3 -3
- package/src/index.ts +7 -7
- package/src/jwt.ts +84 -77
- package/src/options.ts +16 -10
- package/src/service.ts +80 -69
- package/src/strategy.ts +17 -17
package/src/core.ts
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import merge from 'lodash/merge'
|
|
2
|
-
import jsonwebtoken, { SignOptions, Secret, VerifyOptions } from 'jsonwebtoken'
|
|
3
|
-
import { v4 as uuidv4 } from 'uuid'
|
|
4
|
-
import { NotAuthenticated } from '@feathersjs/errors'
|
|
5
|
-
import { createDebug } from '@feathersjs/commons'
|
|
6
|
-
import { Application, Params } from '@feathersjs/feathers'
|
|
7
|
-
import { IncomingMessage, ServerResponse } from 'http'
|
|
8
|
-
import { defaultOptions } from './options'
|
|
1
|
+
import merge from 'lodash/merge'
|
|
2
|
+
import jsonwebtoken, { SignOptions, Secret, VerifyOptions } from 'jsonwebtoken'
|
|
3
|
+
import { v4 as uuidv4 } from 'uuid'
|
|
4
|
+
import { NotAuthenticated } from '@feathersjs/errors'
|
|
5
|
+
import { createDebug } from '@feathersjs/commons'
|
|
6
|
+
import { Application, Params } from '@feathersjs/feathers'
|
|
7
|
+
import { IncomingMessage, ServerResponse } from 'http'
|
|
8
|
+
import { defaultOptions } from './options'
|
|
9
9
|
|
|
10
|
-
const debug = createDebug('@feathersjs/authentication/base')
|
|
10
|
+
const debug = createDebug('@feathersjs/authentication/base')
|
|
11
11
|
|
|
12
12
|
export interface AuthenticationResult {
|
|
13
|
-
[key: string]: any
|
|
13
|
+
[key: string]: any
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export interface AuthenticationRequest {
|
|
17
|
-
strategy?: string
|
|
18
|
-
[key: string]: any
|
|
17
|
+
strategy?: string
|
|
18
|
+
[key: string]: any
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export interface AuthenticationParams extends Params {
|
|
22
|
-
payload?: { [key: string]: any }
|
|
23
|
-
jwtOptions?: SignOptions
|
|
24
|
-
authStrategies?: string[]
|
|
25
|
-
secret?: string
|
|
26
|
-
[key: string]: any
|
|
22
|
+
payload?: { [key: string]: any }
|
|
23
|
+
jwtOptions?: SignOptions
|
|
24
|
+
authStrategies?: string[]
|
|
25
|
+
secret?: string
|
|
26
|
+
[key: string]: any
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export type ConnectionEvent = 'login' | 'logout' | 'disconnect'
|
|
29
|
+
export type ConnectionEvent = 'login' | 'logout' | 'disconnect'
|
|
30
30
|
|
|
31
31
|
export interface AuthenticationStrategy {
|
|
32
32
|
/**
|
|
@@ -34,30 +34,30 @@ export interface AuthenticationStrategy {
|
|
|
34
34
|
*
|
|
35
35
|
* @param auth The AuthenticationService
|
|
36
36
|
*/
|
|
37
|
-
setAuthentication?
|
|
37
|
+
setAuthentication?(auth: AuthenticationBase): void
|
|
38
38
|
/**
|
|
39
39
|
* Implement this method to get access to the Feathers application
|
|
40
40
|
*
|
|
41
41
|
* @param app The Feathers application instance
|
|
42
42
|
*/
|
|
43
|
-
setApplication?
|
|
43
|
+
setApplication?(app: Application): void
|
|
44
44
|
/**
|
|
45
45
|
* Implement this method to get access to the strategy name
|
|
46
46
|
*
|
|
47
47
|
* @param name The name of the strategy
|
|
48
48
|
*/
|
|
49
|
-
setName?
|
|
49
|
+
setName?(name: string): void
|
|
50
50
|
/**
|
|
51
51
|
* Implement this method to verify the current configuration
|
|
52
52
|
* and throw an error if it is invalid.
|
|
53
53
|
*/
|
|
54
|
-
verifyConfiguration?
|
|
54
|
+
verifyConfiguration?(): void
|
|
55
55
|
/**
|
|
56
56
|
* Implement this method to setup this strategy
|
|
57
57
|
* @param auth The AuthenticationService
|
|
58
58
|
* @param name The name of the strategy
|
|
59
59
|
*/
|
|
60
|
-
setup?
|
|
60
|
+
setup?(auth: AuthenticationBase, name: string): Promise<void>
|
|
61
61
|
/**
|
|
62
62
|
* Authenticate an authentication request with this strategy.
|
|
63
63
|
* Should throw an error if the strategy did not succeed.
|
|
@@ -65,35 +65,38 @@ export interface AuthenticationStrategy {
|
|
|
65
65
|
* @param authentication The authentication request
|
|
66
66
|
* @param params The service call parameters
|
|
67
67
|
*/
|
|
68
|
-
authenticate?
|
|
68
|
+
authenticate?(
|
|
69
|
+
authentication: AuthenticationRequest,
|
|
70
|
+
params: AuthenticationParams
|
|
71
|
+
): Promise<AuthenticationResult>
|
|
69
72
|
/**
|
|
70
73
|
* Update a real-time connection according to this strategy.
|
|
71
74
|
*
|
|
72
75
|
* @param connection The real-time connection
|
|
73
76
|
* @param context The hook context
|
|
74
77
|
*/
|
|
75
|
-
handleConnection?
|
|
78
|
+
handleConnection?(event: ConnectionEvent, connection: any, authResult?: AuthenticationResult): Promise<void>
|
|
76
79
|
/**
|
|
77
80
|
* Parse a basic HTTP request and response for authentication request information.
|
|
78
81
|
*
|
|
79
82
|
* @param req The HTTP request
|
|
80
83
|
* @param res The HTTP response
|
|
81
84
|
*/
|
|
82
|
-
parse?
|
|
85
|
+
parse?(req: IncomingMessage, res: ServerResponse): Promise<AuthenticationRequest | null>
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
export interface JwtVerifyOptions extends VerifyOptions {
|
|
86
|
-
algorithm?: string | string[]
|
|
89
|
+
algorithm?: string | string[]
|
|
87
90
|
}
|
|
88
91
|
|
|
89
92
|
/**
|
|
90
93
|
* A base class for managing authentication strategies and creating and verifying JWTs
|
|
91
94
|
*/
|
|
92
95
|
export class AuthenticationBase {
|
|
93
|
-
app: Application
|
|
94
|
-
strategies: { [key: string]: AuthenticationStrategy }
|
|
95
|
-
configKey: string
|
|
96
|
-
isReady: boolean
|
|
96
|
+
app: Application
|
|
97
|
+
strategies: { [key: string]: AuthenticationStrategy }
|
|
98
|
+
configKey: string
|
|
99
|
+
isReady: boolean
|
|
97
100
|
|
|
98
101
|
/**
|
|
99
102
|
* Create a new authentication service.
|
|
@@ -102,33 +105,33 @@ export class AuthenticationBase {
|
|
|
102
105
|
* @param configKey The configuration key name in `app.get` (default: `authentication`)
|
|
103
106
|
* @param options Optional initial options
|
|
104
107
|
*/
|
|
105
|
-
constructor
|
|
108
|
+
constructor(app: Application, configKey = 'authentication', options = {}) {
|
|
106
109
|
if (!app || typeof app.use !== 'function') {
|
|
107
|
-
throw new Error('An application instance has to be passed to the authentication service')
|
|
110
|
+
throw new Error('An application instance has to be passed to the authentication service')
|
|
108
111
|
}
|
|
109
112
|
|
|
110
|
-
this.app = app
|
|
111
|
-
this.strategies = {}
|
|
112
|
-
this.configKey = configKey
|
|
113
|
-
this.isReady = false
|
|
113
|
+
this.app = app
|
|
114
|
+
this.strategies = {}
|
|
115
|
+
this.configKey = configKey
|
|
116
|
+
this.isReady = false
|
|
114
117
|
|
|
115
|
-
app.set('defaultAuthentication', app.get('defaultAuthentication') || configKey)
|
|
116
|
-
app.set(configKey, merge({}, app.get(configKey), options))
|
|
118
|
+
app.set('defaultAuthentication', app.get('defaultAuthentication') || configKey)
|
|
119
|
+
app.set(configKey, merge({}, app.get(configKey), options))
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
/**
|
|
120
123
|
* Return the current configuration from the application
|
|
121
124
|
*/
|
|
122
|
-
get configuration
|
|
125
|
+
get configuration() {
|
|
123
126
|
// Always returns a copy of the authentication configuration
|
|
124
|
-
return Object.assign({}, defaultOptions, this.app.get(this.configKey))
|
|
127
|
+
return Object.assign({}, defaultOptions, this.app.get(this.configKey))
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
/**
|
|
128
131
|
* A list of all registered strategy names
|
|
129
132
|
*/
|
|
130
|
-
get strategyNames
|
|
131
|
-
return Object.keys(this.strategies)
|
|
133
|
+
get strategyNames() {
|
|
134
|
+
return Object.keys(this.strategies)
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
/**
|
|
@@ -137,29 +140,29 @@ export class AuthenticationBase {
|
|
|
137
140
|
* @param name The name to register the strategy under
|
|
138
141
|
* @param strategy The authentication strategy instance
|
|
139
142
|
*/
|
|
140
|
-
register
|
|
143
|
+
register(name: string, strategy: AuthenticationStrategy) {
|
|
141
144
|
// Call the functions a strategy can implement
|
|
142
145
|
if (typeof strategy.setName === 'function') {
|
|
143
|
-
strategy.setName(name)
|
|
146
|
+
strategy.setName(name)
|
|
144
147
|
}
|
|
145
148
|
|
|
146
149
|
if (typeof strategy.setApplication === 'function') {
|
|
147
|
-
strategy.setApplication(this.app)
|
|
150
|
+
strategy.setApplication(this.app)
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
if (typeof strategy.setAuthentication === 'function') {
|
|
151
|
-
strategy.setAuthentication(this)
|
|
154
|
+
strategy.setAuthentication(this)
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
if (typeof strategy.verifyConfiguration === 'function') {
|
|
155
|
-
strategy.verifyConfiguration()
|
|
158
|
+
strategy.verifyConfiguration()
|
|
156
159
|
}
|
|
157
160
|
|
|
158
161
|
// Register strategy as name
|
|
159
|
-
this.strategies[name] = strategy
|
|
162
|
+
this.strategies[name] = strategy
|
|
160
163
|
|
|
161
164
|
if (this.isReady) {
|
|
162
|
-
strategy.setup?.(this, name)
|
|
165
|
+
strategy.setup?.(this, name)
|
|
163
166
|
}
|
|
164
167
|
}
|
|
165
168
|
|
|
@@ -168,9 +171,8 @@ export class AuthenticationBase {
|
|
|
168
171
|
*
|
|
169
172
|
* @param names The list or strategy names
|
|
170
173
|
*/
|
|
171
|
-
getStrategies
|
|
172
|
-
return names.map(name => this.strategies[name])
|
|
173
|
-
.filter(current => !!current);
|
|
174
|
+
getStrategies(...names: string[]) {
|
|
175
|
+
return names.map((name) => this.strategies[name]).filter((current) => !!current)
|
|
174
176
|
}
|
|
175
177
|
|
|
176
178
|
/**
|
|
@@ -179,8 +181,8 @@ export class AuthenticationBase {
|
|
|
179
181
|
* @param name The strategy name
|
|
180
182
|
* @returns The authentication strategy or undefined
|
|
181
183
|
*/
|
|
182
|
-
getStrategy
|
|
183
|
-
return this.strategies[name]
|
|
184
|
+
getStrategy(name: string) {
|
|
185
|
+
return this.strategies[name]
|
|
184
186
|
}
|
|
185
187
|
|
|
186
188
|
/**
|
|
@@ -190,19 +192,23 @@ export class AuthenticationBase {
|
|
|
190
192
|
* @param optsOverride The options to extend the defaults (`configuration.jwtOptions`) with
|
|
191
193
|
* @param secretOverride Use a different secret instead
|
|
192
194
|
*/
|
|
193
|
-
async createAccessToken
|
|
194
|
-
|
|
195
|
+
async createAccessToken(
|
|
196
|
+
payload: string | Buffer | object,
|
|
197
|
+
optsOverride?: SignOptions,
|
|
198
|
+
secretOverride?: Secret
|
|
199
|
+
) {
|
|
200
|
+
const { secret, jwtOptions } = this.configuration
|
|
195
201
|
// Use configuration by default but allow overriding the secret
|
|
196
|
-
const jwtSecret = secretOverride || secret
|
|
202
|
+
const jwtSecret = secretOverride || secret
|
|
197
203
|
// Default jwt options merged with additional options
|
|
198
|
-
const options = merge({}, jwtOptions, optsOverride)
|
|
204
|
+
const options = merge({}, jwtOptions, optsOverride)
|
|
199
205
|
|
|
200
206
|
if (!options.jwtid) {
|
|
201
207
|
// Generate a UUID as JWT ID by default
|
|
202
|
-
options.jwtid = uuidv4()
|
|
208
|
+
options.jwtid = uuidv4()
|
|
203
209
|
}
|
|
204
210
|
|
|
205
|
-
return jsonwebtoken.sign(payload, jwtSecret, options)
|
|
211
|
+
return jsonwebtoken.sign(payload, jwtSecret, options)
|
|
206
212
|
}
|
|
207
213
|
|
|
208
214
|
/**
|
|
@@ -212,24 +218,24 @@ export class AuthenticationBase {
|
|
|
212
218
|
* @param optsOverride The options to extend the defaults (`configuration.jwtOptions`) with
|
|
213
219
|
* @param secretOverride Use a different secret instead
|
|
214
220
|
*/
|
|
215
|
-
async verifyAccessToken
|
|
216
|
-
const { secret, jwtOptions } = this.configuration
|
|
217
|
-
const jwtSecret = secretOverride || secret
|
|
218
|
-
const options = merge({}, jwtOptions, optsOverride)
|
|
219
|
-
const { algorithm } = options
|
|
221
|
+
async verifyAccessToken(accessToken: string, optsOverride?: JwtVerifyOptions, secretOverride?: Secret) {
|
|
222
|
+
const { secret, jwtOptions } = this.configuration
|
|
223
|
+
const jwtSecret = secretOverride || secret
|
|
224
|
+
const options = merge({}, jwtOptions, optsOverride)
|
|
225
|
+
const { algorithm } = options
|
|
220
226
|
|
|
221
227
|
// Normalize the `algorithm` setting into the algorithms array
|
|
222
228
|
if (algorithm && !options.algorithms) {
|
|
223
|
-
options.algorithms = Array.isArray(algorithm) ? algorithm : [
|
|
224
|
-
delete options.algorithm
|
|
229
|
+
options.algorithms = Array.isArray(algorithm) ? algorithm : [algorithm]
|
|
230
|
+
delete options.algorithm
|
|
225
231
|
}
|
|
226
232
|
|
|
227
233
|
try {
|
|
228
|
-
const verified = jsonwebtoken.verify(accessToken, jwtSecret, options)
|
|
234
|
+
const verified = jsonwebtoken.verify(accessToken, jwtSecret, options)
|
|
229
235
|
|
|
230
|
-
return verified as any
|
|
236
|
+
return verified as any
|
|
231
237
|
} catch (error: any) {
|
|
232
|
-
throw new NotAuthenticated(error.message, error)
|
|
238
|
+
throw new NotAuthenticated(error.message, error)
|
|
233
239
|
}
|
|
234
240
|
}
|
|
235
241
|
|
|
@@ -240,33 +246,40 @@ export class AuthenticationBase {
|
|
|
240
246
|
* @param params Service call parameters
|
|
241
247
|
* @param allowed A list of allowed strategy names
|
|
242
248
|
*/
|
|
243
|
-
async authenticate
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
249
|
+
async authenticate(
|
|
250
|
+
authentication: AuthenticationRequest,
|
|
251
|
+
params: AuthenticationParams,
|
|
252
|
+
...allowed: string[]
|
|
253
|
+
) {
|
|
254
|
+
const { strategy } = authentication || {}
|
|
255
|
+
const [authStrategy] = this.getStrategies(strategy)
|
|
256
|
+
const strategyAllowed = allowed.includes(strategy)
|
|
247
257
|
|
|
248
|
-
debug('Running authenticate for strategy', strategy, allowed)
|
|
258
|
+
debug('Running authenticate for strategy', strategy, allowed)
|
|
249
259
|
|
|
250
260
|
if (!authentication || !authStrategy || !strategyAllowed) {
|
|
251
|
-
const additionalInfo =
|
|
252
|
-
(!
|
|
261
|
+
const additionalInfo =
|
|
262
|
+
(!strategy && ' (no `strategy` set)') ||
|
|
263
|
+
(!strategyAllowed && ' (strategy not allowed in authStrategies)') ||
|
|
264
|
+
''
|
|
253
265
|
|
|
254
266
|
// If there are no valid strategies or `authentication` is not an object
|
|
255
|
-
throw new NotAuthenticated('Invalid authentication information' + additionalInfo)
|
|
267
|
+
throw new NotAuthenticated('Invalid authentication information' + additionalInfo)
|
|
256
268
|
}
|
|
257
269
|
|
|
258
270
|
return authStrategy.authenticate(authentication, {
|
|
259
271
|
...params,
|
|
260
272
|
authenticated: true
|
|
261
|
-
})
|
|
273
|
+
})
|
|
262
274
|
}
|
|
263
275
|
|
|
264
|
-
async handleConnection
|
|
265
|
-
const strategies = this.getStrategies(...Object.keys(this.strategies))
|
|
266
|
-
|
|
276
|
+
async handleConnection(event: ConnectionEvent, connection: any, authResult?: AuthenticationResult) {
|
|
277
|
+
const strategies = this.getStrategies(...Object.keys(this.strategies)).filter(
|
|
278
|
+
(current) => typeof current.handleConnection === 'function'
|
|
279
|
+
)
|
|
267
280
|
|
|
268
281
|
for (const strategy of strategies) {
|
|
269
|
-
await strategy.handleConnection(event, connection, authResult)
|
|
282
|
+
await strategy.handleConnection(event, connection, authResult)
|
|
270
283
|
}
|
|
271
284
|
}
|
|
272
285
|
|
|
@@ -277,30 +290,29 @@ export class AuthenticationBase {
|
|
|
277
290
|
* @param res The HTTP response
|
|
278
291
|
* @param names A list of strategies to use
|
|
279
292
|
*/
|
|
280
|
-
async parse
|
|
281
|
-
const strategies = this.getStrategies(...names)
|
|
282
|
-
.filter(current => typeof current.parse === 'function');
|
|
293
|
+
async parse(req: IncomingMessage, res: ServerResponse, ...names: string[]) {
|
|
294
|
+
const strategies = this.getStrategies(...names).filter((current) => typeof current.parse === 'function')
|
|
283
295
|
|
|
284
|
-
debug('Strategies parsing HTTP header for authentication information', names)
|
|
296
|
+
debug('Strategies parsing HTTP header for authentication information', names)
|
|
285
297
|
|
|
286
298
|
for (const authStrategy of strategies) {
|
|
287
|
-
const value = await authStrategy.parse(req, res)
|
|
299
|
+
const value = await authStrategy.parse(req, res)
|
|
288
300
|
|
|
289
301
|
if (value !== null) {
|
|
290
|
-
return value
|
|
302
|
+
return value
|
|
291
303
|
}
|
|
292
304
|
}
|
|
293
305
|
|
|
294
|
-
return null
|
|
306
|
+
return null
|
|
295
307
|
}
|
|
296
308
|
|
|
297
|
-
async setup
|
|
298
|
-
this.isReady = true
|
|
309
|
+
async setup() {
|
|
310
|
+
this.isReady = true
|
|
299
311
|
|
|
300
312
|
for (const name of Object.keys(this.strategies)) {
|
|
301
|
-
const strategy = this.strategies[name]
|
|
313
|
+
const strategy = this.strategies[name]
|
|
302
314
|
|
|
303
|
-
await strategy.setup?.(this, name)
|
|
315
|
+
await strategy.setup?.(this, name)
|
|
304
316
|
}
|
|
305
317
|
}
|
|
306
318
|
}
|
|
@@ -1,63 +1,67 @@
|
|
|
1
|
-
import flatten from 'lodash/flatten'
|
|
2
|
-
import omit from 'lodash/omit'
|
|
3
|
-
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
4
|
-
import { NotAuthenticated } from '@feathersjs/errors'
|
|
5
|
-
import { createDebug } from '@feathersjs/commons'
|
|
1
|
+
import flatten from 'lodash/flatten'
|
|
2
|
+
import omit from 'lodash/omit'
|
|
3
|
+
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
4
|
+
import { NotAuthenticated } from '@feathersjs/errors'
|
|
5
|
+
import { createDebug } from '@feathersjs/commons'
|
|
6
6
|
|
|
7
|
-
const debug = createDebug('@feathersjs/authentication/hooks/authenticate')
|
|
7
|
+
const debug = createDebug('@feathersjs/authentication/hooks/authenticate')
|
|
8
8
|
|
|
9
9
|
export interface AuthenticateHookSettings {
|
|
10
|
-
service?: string
|
|
11
|
-
strategies?: string[]
|
|
10
|
+
service?: string
|
|
11
|
+
strategies?: string[]
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export default (originalSettings: string | AuthenticateHookSettings, ...originalStrategies: string[]) => {
|
|
15
|
-
const settings =
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const settings =
|
|
16
|
+
typeof originalSettings === 'string'
|
|
17
|
+
? { strategies: flatten([originalSettings, ...originalStrategies]) }
|
|
18
|
+
: originalSettings
|
|
18
19
|
|
|
19
20
|
if (!originalSettings || settings.strategies.length === 0) {
|
|
20
|
-
throw new Error('The authenticate hook needs at least one allowed strategy')
|
|
21
|
+
throw new Error('The authenticate hook needs at least one allowed strategy')
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
return async (context: HookContext, _next?: NextFunction) => {
|
|
24
|
-
const next = typeof _next === 'function' ? _next : async () => context
|
|
25
|
-
const { app, params, type, path, service } = context
|
|
26
|
-
const { strategies } = settings
|
|
27
|
-
const { provider, authentication } = params
|
|
28
|
-
const authService = app.defaultAuthentication(settings.service)
|
|
25
|
+
const next = typeof _next === 'function' ? _next : async () => context
|
|
26
|
+
const { app, params, type, path, service } = context
|
|
27
|
+
const { strategies } = settings
|
|
28
|
+
const { provider, authentication } = params
|
|
29
|
+
const authService = app.defaultAuthentication(settings.service)
|
|
29
30
|
|
|
30
|
-
debug(`Running authenticate hook on '${path}'`)
|
|
31
|
+
debug(`Running authenticate hook on '${path}'`)
|
|
31
32
|
|
|
32
33
|
if (type && type !== 'before') {
|
|
33
|
-
throw new NotAuthenticated('The authenticate hook must be used as a before hook')
|
|
34
|
+
throw new NotAuthenticated('The authenticate hook must be used as a before hook')
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
if (!authService || typeof authService.authenticate !== 'function') {
|
|
37
|
-
throw new NotAuthenticated('Could not find a valid authentication service')
|
|
38
|
+
throw new NotAuthenticated('Could not find a valid authentication service')
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
// @ts-ignore
|
|
41
41
|
if (service === authService) {
|
|
42
|
-
throw new NotAuthenticated(
|
|
42
|
+
throw new NotAuthenticated(
|
|
43
|
+
'The authenticate hook does not need to be used on the authentication service'
|
|
44
|
+
)
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
if (params.authenticated === true) {
|
|
46
|
-
return next()
|
|
48
|
+
return next()
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
if (authentication) {
|
|
50
|
-
const authParams = omit(params, 'provider', 'authentication')
|
|
52
|
+
const authParams = omit(params, 'provider', 'authentication')
|
|
51
53
|
|
|
52
|
-
debug('Authenticating with', authentication, strategies)
|
|
54
|
+
debug('Authenticating with', authentication, strategies)
|
|
53
55
|
|
|
54
|
-
const authResult = await authService.authenticate(authentication, authParams, ...strategies)
|
|
56
|
+
const authResult = await authService.authenticate(authentication, authParams, ...strategies)
|
|
55
57
|
|
|
56
|
-
context.params = Object.assign({}, params, omit(authResult, 'accessToken'), {
|
|
58
|
+
context.params = Object.assign({}, params, omit(authResult, 'accessToken'), {
|
|
59
|
+
authenticated: true
|
|
60
|
+
})
|
|
57
61
|
} else if (provider) {
|
|
58
|
-
throw new NotAuthenticated('Not authenticated')
|
|
62
|
+
throw new NotAuthenticated('Not authenticated')
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
return next()
|
|
62
|
-
}
|
|
63
|
-
}
|
|
65
|
+
return next()
|
|
66
|
+
}
|
|
67
|
+
}
|
package/src/hooks/connection.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
2
|
-
import omit from 'lodash/omit'
|
|
3
|
-
import { AuthenticationBase, ConnectionEvent } from '../core'
|
|
1
|
+
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
2
|
+
import omit from 'lodash/omit'
|
|
3
|
+
import { AuthenticationBase, ConnectionEvent } from '../core'
|
|
4
4
|
|
|
5
5
|
export default (event: ConnectionEvent) => async (context: HookContext, next: NextFunction) => {
|
|
6
|
-
await next()
|
|
6
|
+
await next()
|
|
7
7
|
|
|
8
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
result,
|
|
10
|
+
params: { connection }
|
|
11
|
+
} = context
|
|
9
12
|
|
|
10
13
|
if (connection) {
|
|
11
|
-
const service = context.service as unknown as AuthenticationBase
|
|
14
|
+
const service = context.service as unknown as AuthenticationBase
|
|
12
15
|
|
|
13
|
-
Object.assign(connection, omit(result, 'accessToken', 'authentication'))
|
|
16
|
+
Object.assign(connection, omit(result, 'accessToken', 'authentication'))
|
|
14
17
|
|
|
15
|
-
await service.handleConnection(event, connection, result)
|
|
18
|
+
await service.handleConnection(event, connection, result)
|
|
16
19
|
}
|
|
17
|
-
}
|
|
20
|
+
}
|
package/src/hooks/event.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
2
|
-
import { createDebug } from '@feathersjs/commons'
|
|
3
|
-
import { ConnectionEvent } from '../core'
|
|
1
|
+
import { HookContext, NextFunction } from '@feathersjs/feathers'
|
|
2
|
+
import { createDebug } from '@feathersjs/commons'
|
|
3
|
+
import { ConnectionEvent } from '../core'
|
|
4
4
|
|
|
5
|
-
const debug = createDebug('@feathersjs/authentication/hooks/connection')
|
|
5
|
+
const debug = createDebug('@feathersjs/authentication/hooks/connection')
|
|
6
6
|
|
|
7
7
|
export default (event: ConnectionEvent) => async (context: HookContext, next: NextFunction) => {
|
|
8
|
-
await next()
|
|
8
|
+
await next()
|
|
9
9
|
|
|
10
|
-
const { app, result, params } = context
|
|
10
|
+
const { app, result, params } = context
|
|
11
11
|
|
|
12
12
|
if (params.provider && result) {
|
|
13
|
-
debug(`Sending authentication event '${event}'`)
|
|
14
|
-
app.emit(event, result, params, context)
|
|
13
|
+
debug(`Sending authentication event '${event}'`)
|
|
14
|
+
app.emit(event, result, params, context)
|
|
15
15
|
}
|
|
16
|
-
}
|
|
16
|
+
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { default as authenticate } from './authenticate'
|
|
2
|
-
export { default as connection } from './connection'
|
|
3
|
-
export { default as event } from './event'
|
|
1
|
+
export { default as authenticate } from './authenticate'
|
|
2
|
+
export { default as connection } from './connection'
|
|
3
|
+
export { default as event } from './event'
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * as hooks from './hooks'
|
|
2
|
-
export { authenticate } from './hooks'
|
|
1
|
+
export * as hooks from './hooks'
|
|
2
|
+
export { authenticate } from './hooks'
|
|
3
3
|
export {
|
|
4
4
|
AuthenticationBase,
|
|
5
5
|
AuthenticationRequest,
|
|
@@ -7,8 +7,8 @@ export {
|
|
|
7
7
|
AuthenticationStrategy,
|
|
8
8
|
AuthenticationParams,
|
|
9
9
|
ConnectionEvent
|
|
10
|
-
} from './core'
|
|
11
|
-
export { AuthenticationBaseStrategy } from './strategy'
|
|
12
|
-
export { AuthenticationService } from './service'
|
|
13
|
-
export { JWTStrategy } from './jwt'
|
|
14
|
-
export { authenticationSettingsSchema } from './options'
|
|
10
|
+
} from './core'
|
|
11
|
+
export { AuthenticationBaseStrategy } from './strategy'
|
|
12
|
+
export { AuthenticationService } from './service'
|
|
13
|
+
export { JWTStrategy } from './jwt'
|
|
14
|
+
export { authenticationSettingsSchema } from './options'
|