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