@feathersjs/authentication 5.0.0-pre.2 → 5.0.0-pre.22
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 +199 -0
- package/LICENSE +1 -1
- package/README.md +2 -2
- package/lib/core.d.ts +27 -3
- package/lib/core.js +85 -79
- package/lib/core.js.map +1 -1
- package/lib/hooks/authenticate.d.ts +3 -3
- package/lib/hooks/authenticate.js +11 -20
- package/lib/hooks/authenticate.js.map +1 -1
- package/lib/hooks/connection.d.ts +2 -2
- package/lib/hooks/connection.js +7 -17
- package/lib/hooks/connection.js.map +1 -1
- package/lib/hooks/event.d.ts +2 -2
- package/lib/hooks/event.js +5 -17
- package/lib/hooks/event.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 +3 -3
- package/lib/jwt.js +95 -106
- package/lib/jwt.js.map +1 -1
- package/lib/options.d.ts +118 -3
- package/lib/options.js +106 -1
- package/lib/options.js.map +1 -1
- package/lib/service.d.ts +10 -8
- package/lib/service.js +73 -93
- package/lib/service.js.map +1 -1
- package/lib/strategy.d.ts +1 -1
- package/package.json +20 -20
- package/src/core.ts +47 -9
- package/src/hooks/authenticate.ts +8 -9
- package/src/hooks/connection.ts +9 -11
- package/src/hooks/event.ts +6 -6
- package/src/index.ts +4 -6
- package/src/jwt.ts +8 -5
- package/src/options.ts +107 -2
- package/src/service.ts +14 -14
- package/src/strategy.ts +1 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import flatten from 'lodash/flatten';
|
|
2
2
|
import omit from 'lodash/omit';
|
|
3
|
-
import { HookContext } from '@feathersjs/feathers';
|
|
3
|
+
import { HookContext, NextFunction } from '@feathersjs/feathers';
|
|
4
4
|
import { NotAuthenticated } from '@feathersjs/errors';
|
|
5
|
-
import
|
|
5
|
+
import { createDebug } from '@feathersjs/commons';
|
|
6
6
|
|
|
7
|
-
const debug =
|
|
7
|
+
const debug = createDebug('@feathersjs/authentication/hooks/authenticate');
|
|
8
8
|
|
|
9
9
|
export interface AuthenticateHookSettings {
|
|
10
10
|
service?: string;
|
|
11
|
-
strategies
|
|
11
|
+
strategies?: string[];
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export default (originalSettings: string | AuthenticateHookSettings, ...originalStrategies: string[]) => {
|
|
@@ -20,7 +20,8 @@ export default (originalSettings: string | AuthenticateHookSettings, ...original
|
|
|
20
20
|
throw new Error('The authenticate hook needs at least one allowed strategy');
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
return async (context: HookContext
|
|
23
|
+
return async (context: HookContext, _next?: NextFunction) => {
|
|
24
|
+
const next = typeof _next === 'function' ? _next : async () => context;
|
|
24
25
|
const { app, params, type, path, service } = context;
|
|
25
26
|
const { strategies } = settings;
|
|
26
27
|
const { provider, authentication } = params;
|
|
@@ -42,7 +43,7 @@ export default (originalSettings: string | AuthenticateHookSettings, ...original
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
if (params.authenticated === true) {
|
|
45
|
-
return
|
|
46
|
+
return next();
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
if (authentication) {
|
|
@@ -53,12 +54,10 @@ export default (originalSettings: string | AuthenticateHookSettings, ...original
|
|
|
53
54
|
const authResult = await authService.authenticate(authentication, authParams, ...strategies);
|
|
54
55
|
|
|
55
56
|
context.params = Object.assign({}, params, omit(authResult, 'accessToken'), { authenticated: true });
|
|
56
|
-
|
|
57
|
-
return context;
|
|
58
57
|
} else if (provider) {
|
|
59
58
|
throw new NotAuthenticated('Not authenticated');
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
return
|
|
61
|
+
return next();
|
|
63
62
|
};
|
|
64
63
|
};
|
package/src/hooks/connection.ts
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
import { HookContext } from '@feathersjs/feathers';
|
|
1
|
+
import { HookContext, NextFunction } from '@feathersjs/feathers';
|
|
2
2
|
import omit from 'lodash/omit';
|
|
3
3
|
import { AuthenticationBase, ConnectionEvent } from '../core';
|
|
4
4
|
|
|
5
|
-
export default (event: ConnectionEvent) => async (context: HookContext) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (!connection) {
|
|
9
|
-
return context;
|
|
10
|
-
}
|
|
5
|
+
export default (event: ConnectionEvent) => async (context: HookContext, next: NextFunction) => {
|
|
6
|
+
await next();
|
|
11
7
|
|
|
12
|
-
const
|
|
8
|
+
const { result, params: { connection } } = context;
|
|
13
9
|
|
|
14
|
-
|
|
10
|
+
if (connection) {
|
|
11
|
+
const service = context.service as unknown as AuthenticationBase;
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
Object.assign(connection, omit(result, 'accessToken', 'authentication'));
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
await service.handleConnection(event, connection, result);
|
|
16
|
+
}
|
|
19
17
|
};
|
package/src/hooks/event.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { HookContext, NextFunction } from '@feathersjs/feathers';
|
|
2
|
+
import { createDebug } from '@feathersjs/commons';
|
|
3
3
|
import { ConnectionEvent } from '../core';
|
|
4
4
|
|
|
5
|
-
const debug =
|
|
5
|
+
const debug = createDebug('@feathersjs/authentication/hooks/connection');
|
|
6
|
+
|
|
7
|
+
export default (event: ConnectionEvent) => async (context: HookContext, next: NextFunction) => {
|
|
8
|
+
await next();
|
|
6
9
|
|
|
7
|
-
export default (event: ConnectionEvent) => async (context: HookContext) => {
|
|
8
10
|
const { app, result, params } = context;
|
|
9
11
|
|
|
10
12
|
if (params.provider && result) {
|
|
11
13
|
debug(`Sending authentication event '${event}'`);
|
|
12
14
|
app.emit(event, result, params, context);
|
|
13
15
|
}
|
|
14
|
-
|
|
15
|
-
return context;
|
|
16
16
|
};
|
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
10
|
} from './core';
|
|
14
11
|
export { AuthenticationBaseStrategy } from './strategy';
|
|
15
12
|
export { AuthenticationService } from './service';
|
|
16
13
|
export { JWTStrategy } from './jwt';
|
|
14
|
+
export { authenticationSettingsSchema } from './options';
|
package/src/jwt.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
-
import Debug from 'debug';
|
|
3
2
|
import omit from 'lodash/omit';
|
|
4
3
|
import { IncomingMessage } from 'http';
|
|
5
4
|
import { NotAuthenticated } from '@feathersjs/errors';
|
|
6
5
|
import { Params } from '@feathersjs/feathers';
|
|
6
|
+
import { createDebug } from '@feathersjs/commons';
|
|
7
7
|
// @ts-ignore
|
|
8
8
|
import lt from 'long-timeout';
|
|
9
9
|
|
|
10
10
|
import { AuthenticationBaseStrategy } from './strategy';
|
|
11
|
-
import { AuthenticationRequest, AuthenticationResult, ConnectionEvent } from './core';
|
|
11
|
+
import { AuthenticationParams, AuthenticationRequest, AuthenticationResult, ConnectionEvent } from './core';
|
|
12
12
|
|
|
13
|
-
const debug =
|
|
13
|
+
const debug = createDebug('@feathersjs/authentication/jwt');
|
|
14
14
|
const SPLIT_HEADER = /(\S+)\s+(\S+)/;
|
|
15
15
|
|
|
16
16
|
export class JWTStrategy extends AuthenticationBaseStrategy {
|
|
@@ -116,7 +116,7 @@ export class JWTStrategy extends AuthenticationBaseStrategy {
|
|
|
116
116
|
return authResult.authentication.payload.sub;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
async authenticate (authentication: AuthenticationRequest, params:
|
|
119
|
+
async authenticate (authentication: AuthenticationRequest, params: AuthenticationParams) {
|
|
120
120
|
const { accessToken } = authentication;
|
|
121
121
|
const { entity } = this.configuration;
|
|
122
122
|
|
|
@@ -147,7 +147,10 @@ export class JWTStrategy extends AuthenticationBaseStrategy {
|
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
async parse (req: IncomingMessage) {
|
|
150
|
+
async parse (req: IncomingMessage): Promise<{
|
|
151
|
+
strategy: string;
|
|
152
|
+
accessToken: string;
|
|
153
|
+
} | null> {
|
|
151
154
|
const { header, schemes }: { header: string, schemes: string[] } = this.configuration;
|
|
152
155
|
const headerValue = req.headers && req.headers[header.toLowerCase()];
|
|
153
156
|
|
package/src/options.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
authStrategies: [],
|
|
1
|
+
export const defaultOptions = {
|
|
2
|
+
authStrategies: [] as string[],
|
|
3
3
|
jwtOptions: {
|
|
4
4
|
header: { typ: 'access' }, // by default is an access token but can be any type
|
|
5
5
|
audience: 'https://yourdomain.com', // The resource server where the token is processed
|
|
@@ -8,3 +8,108 @@ export default {
|
|
|
8
8
|
expiresIn: '1d'
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
|
+
|
|
12
|
+
export const authenticationSettingsSchema = {
|
|
13
|
+
type: 'object',
|
|
14
|
+
required: ['secret', 'entity', 'authStrategies'],
|
|
15
|
+
properties: {
|
|
16
|
+
secret: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
description: 'The JWT signing secret'
|
|
19
|
+
},
|
|
20
|
+
entity: {
|
|
21
|
+
oneOf: [{
|
|
22
|
+
type: 'null'
|
|
23
|
+
}, {
|
|
24
|
+
type: 'string'
|
|
25
|
+
}],
|
|
26
|
+
description: 'The name of the authentication entity (e.g. user)'
|
|
27
|
+
},
|
|
28
|
+
entityId: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description: 'The name of the authentication entity id property'
|
|
31
|
+
},
|
|
32
|
+
service: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'The path of the entity service'
|
|
35
|
+
},
|
|
36
|
+
authStrategies: {
|
|
37
|
+
type: 'array',
|
|
38
|
+
items: { type: 'string' },
|
|
39
|
+
description: 'A list of authentication strategy names that are allowed to create JWT access tokens'
|
|
40
|
+
},
|
|
41
|
+
parseStrategies: {
|
|
42
|
+
type: 'array',
|
|
43
|
+
items: { type: 'string' },
|
|
44
|
+
description: 'A list of authentication strategy names that should parse HTTP headers for authentication information (defaults to `authStrategies`)'
|
|
45
|
+
},
|
|
46
|
+
jwtOptions: {
|
|
47
|
+
type: 'object'
|
|
48
|
+
},
|
|
49
|
+
jwt: {
|
|
50
|
+
type: 'object',
|
|
51
|
+
properties: {
|
|
52
|
+
header: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
default: 'Authorization',
|
|
55
|
+
description: 'The HTTP header containing the JWT'
|
|
56
|
+
},
|
|
57
|
+
schemes: {
|
|
58
|
+
type: 'array',
|
|
59
|
+
items: { type: 'string' },
|
|
60
|
+
description: 'An array of schemes to support'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
local: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
required: ['usernameField', 'passwordField'],
|
|
67
|
+
properties: {
|
|
68
|
+
usernameField: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: 'Name of the username field (e.g. `email`)'
|
|
71
|
+
},
|
|
72
|
+
passwordField: {
|
|
73
|
+
type: 'string',
|
|
74
|
+
description: 'Name of the password field (e.g. `password`)'
|
|
75
|
+
},
|
|
76
|
+
hashSize: {
|
|
77
|
+
type: 'number',
|
|
78
|
+
description: 'The BCrypt salt length'
|
|
79
|
+
},
|
|
80
|
+
errorMessage: {
|
|
81
|
+
type: 'string',
|
|
82
|
+
default: 'Invalid login',
|
|
83
|
+
description: 'The error message to return on errors'
|
|
84
|
+
},
|
|
85
|
+
entityUsernameField: {
|
|
86
|
+
type: 'string',
|
|
87
|
+
description: 'Name of the username field on the entity if authentication request data and entity field names are different'
|
|
88
|
+
},
|
|
89
|
+
entityPasswordField: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Name of the password field on the entity if authentication request data and entity field names are different'
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
oauth: {
|
|
96
|
+
type: 'object',
|
|
97
|
+
properties: {
|
|
98
|
+
redirect: {
|
|
99
|
+
type: 'string'
|
|
100
|
+
},
|
|
101
|
+
origins: {
|
|
102
|
+
type: 'array',
|
|
103
|
+
items: { type: 'string' }
|
|
104
|
+
},
|
|
105
|
+
defaults: {
|
|
106
|
+
type: 'object',
|
|
107
|
+
properties: {
|
|
108
|
+
key: { type: 'string' },
|
|
109
|
+
secret: { type: 'string' }
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} as const;
|
package/src/service.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import Debug from 'debug';
|
|
2
1
|
import merge from 'lodash/merge';
|
|
3
2
|
import { NotAuthenticated } from '@feathersjs/errors';
|
|
4
|
-
import { AuthenticationBase, AuthenticationResult, AuthenticationRequest } from './core';
|
|
3
|
+
import { AuthenticationBase, AuthenticationResult, AuthenticationRequest, AuthenticationParams } from './core';
|
|
5
4
|
import { connection, event } from './hooks';
|
|
6
5
|
import '@feathersjs/transport-commons';
|
|
7
|
-
import {
|
|
6
|
+
import { createDebug } from '@feathersjs/commons';
|
|
7
|
+
import { ServiceMethods, ServiceAddons } from '@feathersjs/feathers';
|
|
8
8
|
import jsonwebtoken from 'jsonwebtoken';
|
|
9
9
|
|
|
10
|
-
const debug =
|
|
10
|
+
const debug = createDebug('@feathersjs/authentication/service');
|
|
11
11
|
|
|
12
12
|
declare module '@feathersjs/feathers/lib/declarations' {
|
|
13
|
-
interface FeathersApplication<
|
|
13
|
+
interface FeathersApplication<Services, Settings> { // eslint-disable-line
|
|
14
14
|
/**
|
|
15
15
|
* Returns the default authentication service or the
|
|
16
16
|
* authentication service for a given path.
|
|
@@ -29,7 +29,7 @@ declare module '@feathersjs/feathers/lib/declarations' {
|
|
|
29
29
|
// eslint-disable-next-line
|
|
30
30
|
export interface AuthenticationService extends ServiceAddons<AuthenticationResult, AuthenticationResult> {}
|
|
31
31
|
|
|
32
|
-
export class AuthenticationService extends AuthenticationBase implements Partial<ServiceMethods<AuthenticationResult>> {
|
|
32
|
+
export class AuthenticationService extends AuthenticationBase implements Partial<ServiceMethods<AuthenticationResult, AuthenticationRequest, AuthenticationParams>> {
|
|
33
33
|
constructor (app: any, configKey = 'authentication', options = {}) {
|
|
34
34
|
super(app, configKey, options);
|
|
35
35
|
|
|
@@ -51,7 +51,7 @@ export class AuthenticationService extends AuthenticationBase implements Partial
|
|
|
51
51
|
* @param _authResult The current authentication result
|
|
52
52
|
* @param params The service call parameters
|
|
53
53
|
*/
|
|
54
|
-
async getPayload (_authResult: AuthenticationResult, params:
|
|
54
|
+
async getPayload (_authResult: AuthenticationResult, params: AuthenticationParams) {
|
|
55
55
|
// Uses `params.payload` or returns an empty payload
|
|
56
56
|
const { payload = {} } = params;
|
|
57
57
|
|
|
@@ -65,7 +65,7 @@ export class AuthenticationService extends AuthenticationBase implements Partial
|
|
|
65
65
|
* @param authResult The authentication result
|
|
66
66
|
* @param params Service call parameters
|
|
67
67
|
*/
|
|
68
|
-
async getTokenOptions (authResult: AuthenticationResult, params:
|
|
68
|
+
async getTokenOptions (authResult: AuthenticationResult, params: AuthenticationParams) {
|
|
69
69
|
const { service, entity, entityId } = this.configuration;
|
|
70
70
|
const jwtOptions = merge({}, params.jwtOptions, params.jwt);
|
|
71
71
|
const value = service && entity && authResult[entity];
|
|
@@ -92,7 +92,7 @@ export class AuthenticationService extends AuthenticationBase implements Partial
|
|
|
92
92
|
* @param data The authentication request (should include `strategy` key)
|
|
93
93
|
* @param params Service call parameters
|
|
94
94
|
*/
|
|
95
|
-
async create (data: AuthenticationRequest, params?:
|
|
95
|
+
async create (data: AuthenticationRequest, params?: AuthenticationParams) {
|
|
96
96
|
const authStrategies = params.authStrategies || this.configuration.authStrategies;
|
|
97
97
|
|
|
98
98
|
if (!authStrategies.length) {
|
|
@@ -131,7 +131,7 @@ export class AuthenticationService extends AuthenticationBase implements Partial
|
|
|
131
131
|
* @param id The JWT to remove or null
|
|
132
132
|
* @param params Service call parameters
|
|
133
133
|
*/
|
|
134
|
-
async remove (id: string | null, params?:
|
|
134
|
+
async remove (id: string | null, params?: AuthenticationParams) {
|
|
135
135
|
const { authentication } = params;
|
|
136
136
|
const { authStrategies } = this.configuration;
|
|
137
137
|
|
|
@@ -149,6 +149,8 @@ export class AuthenticationService extends AuthenticationBase implements Partial
|
|
|
149
149
|
* Validates the service configuration.
|
|
150
150
|
*/
|
|
151
151
|
async setup () {
|
|
152
|
+
await super.setup();
|
|
153
|
+
|
|
152
154
|
// The setup method checks for valid settings and registers the
|
|
153
155
|
// connection and event (login, logout) hooks
|
|
154
156
|
const { secret, service, entity, entityId } = this.configuration;
|
|
@@ -172,10 +174,8 @@ export class AuthenticationService extends AuthenticationBase implements Partial
|
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
(this as any).hooks({
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
remove: [ connection('logout'), event('logout') ]
|
|
178
|
-
}
|
|
177
|
+
create: [ connection('login'), event('login') ],
|
|
178
|
+
remove: [ connection('logout'), event('logout') ]
|
|
179
179
|
});
|
|
180
180
|
|
|
181
181
|
this.app.on('disconnect', async (connection) => {
|
package/src/strategy.ts
CHANGED
|
@@ -22,7 +22,7 @@ export class AuthenticationBaseStrategy implements AuthenticationStrategy {
|
|
|
22
22
|
return this.authentication.configuration[this.name];
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
get entityService (): Service
|
|
25
|
+
get entityService (): Service {
|
|
26
26
|
const { service } = this.configuration;
|
|
27
27
|
|
|
28
28
|
if (!service) {
|