@feathersjs/authentication-oauth 5.0.0-pre.3 → 5.0.0-pre.31

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/src/strategy.ts CHANGED
@@ -1,159 +1,176 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
2
- // @ts-ignore
3
- import querystring from 'querystring';
4
1
  import {
5
- AuthenticationRequest, AuthenticationBaseStrategy, AuthenticationResult
6
- } from '@feathersjs/authentication';
7
- import { Params } from '@feathersjs/feathers';
8
- import { NotAuthenticated } from '@feathersjs/errors';
9
- import { createDebug } from '@feathersjs/commons';
10
-
11
- const debug = createDebug('@feathersjs/authentication-oauth/strategy');
2
+ AuthenticationRequest,
3
+ AuthenticationBaseStrategy,
4
+ AuthenticationResult,
5
+ AuthenticationParams
6
+ } from '@feathersjs/authentication'
7
+ import { Params } from '@feathersjs/feathers'
8
+ import { NotAuthenticated } from '@feathersjs/errors'
9
+ import { createDebug, _ } from '@feathersjs/commons'
10
+ import qs from 'qs'
11
+
12
+ const debug = createDebug('@feathersjs/authentication-oauth/strategy')
12
13
 
13
14
  export interface OAuthProfile {
14
- id?: string|number;
15
- [key: string]: any;
15
+ id?: string | number
16
+ [key: string]: any
16
17
  }
17
18
 
18
19
  export class OAuthStrategy extends AuthenticationBaseStrategy {
19
- get configuration () {
20
- const { entity, service, entityId, oauth } = this.authentication.configuration;
21
- const config = oauth[this.name];
20
+ get configuration() {
21
+ const { entity, service, entityId, oauth } = this.authentication.configuration
22
+ const config = oauth[this.name] as any
22
23
 
23
24
  return {
24
25
  entity,
25
26
  service,
26
27
  entityId,
27
28
  ...config
28
- };
29
+ }
29
30
  }
30
31
 
31
- get entityId (): string {
32
- const { entityService } = this;
32
+ get entityId(): string {
33
+ const { entityService } = this
33
34
 
34
- return this.configuration.entityId || (entityService && (entityService as any).id);
35
+ return this.configuration.entityId || (entityService && (entityService as any).id)
35
36
  }
36
37
 
37
- async getEntityQuery (profile: OAuthProfile, _params: Params) {
38
+ async getEntityQuery(profile: OAuthProfile, _params: Params) {
38
39
  return {
39
40
  [`${this.name}Id`]: profile.sub || profile.id
40
- };
41
+ }
41
42
  }
42
43
 
43
- async getEntityData (profile: OAuthProfile, _existingEntity: any, _params: Params) {
44
+ async getEntityData(profile: OAuthProfile, _existingEntity: any, _params: Params) {
44
45
  return {
45
46
  [`${this.name}Id`]: profile.sub || profile.id
46
- };
47
+ }
47
48
  }
48
49
 
49
- async getProfile (data: AuthenticationRequest, _params: Params) {
50
+ async getProfile(data: AuthenticationRequest, _params: Params) {
50
51
  return data.profile
51
52
  }
52
53
 
53
- async getCurrentEntity (params: Params) {
54
- const { authentication } = params;
55
- const { entity } = this.configuration;
54
+ async getCurrentEntity(params: Params) {
55
+ const { authentication } = params
56
+ const { entity } = this.configuration
56
57
 
57
58
  if (authentication && authentication.strategy) {
58
- debug('getCurrentEntity with authentication', authentication);
59
+ debug('getCurrentEntity with authentication', authentication)
60
+
61
+ const { strategy } = authentication
62
+ const authResult = await this.authentication.authenticate(authentication, params, strategy)
63
+
64
+ return authResult[entity]
65
+ }
59
66
 
60
- const { strategy } = authentication;
61
- const authResult = await this.authentication
62
- .authenticate(authentication, params, strategy);
67
+ return null
68
+ }
69
+
70
+ async getAllowedOrigin(params?: Params) {
71
+ const { redirect, origins = this.app.get('origins') } = this.authentication.configuration.oauth
72
+
73
+ if (Array.isArray(origins)) {
74
+ const referer = params?.headers?.referer || origins[0]
75
+ const allowedOrigin = origins.find((current) => referer.toLowerCase().startsWith(current.toLowerCase()))
76
+
77
+ if (!allowedOrigin) {
78
+ throw new NotAuthenticated(`Referer "${referer}" is not allowed.`)
79
+ }
63
80
 
64
- return authResult[entity];
81
+ return allowedOrigin
65
82
  }
66
83
 
67
- return null;
84
+ return redirect
68
85
  }
69
86
 
70
- async getRedirect (data: AuthenticationResult|Error, params?: Params): Promise<string | null> {
71
- const queryRedirect = (params && params.redirect) || '';
72
- const { redirect } = this.authentication.configuration.oauth;
87
+ async getRedirect(
88
+ data: AuthenticationResult | Error,
89
+ params?: AuthenticationParams
90
+ ): Promise<string | null> {
91
+ const queryRedirect = (params && params.redirect) || ''
92
+ const redirect = await this.getAllowedOrigin(params)
73
93
 
74
94
  if (!redirect) {
75
- return null;
95
+ return null
76
96
  }
77
97
 
78
- const redirectUrl = `${redirect}${queryRedirect}`;
79
- const separator = redirect.endsWith('?') ? '' :
80
- (redirect.indexOf('#') !== -1 ? '?' : '#');
81
- const authResult: AuthenticationResult = data;
82
- const query = authResult.accessToken ? {
83
- access_token: authResult.accessToken
84
- } : {
85
- error: data.message || 'OAuth Authentication not successful'
86
- };
87
-
88
- return `${redirectUrl}${separator}${querystring.stringify(query)}`;
98
+ const redirectUrl = `${redirect}${queryRedirect}`
99
+ const separator = redirect.endsWith('?') ? '' : redirect.indexOf('#') !== -1 ? '?' : '#'
100
+ const authResult: AuthenticationResult = data
101
+ const query = authResult.accessToken
102
+ ? { access_token: authResult.accessToken }
103
+ : { error: data.message || 'OAuth Authentication not successful' }
104
+
105
+ return `${redirectUrl}${separator}${qs.stringify(query)}`
89
106
  }
90
107
 
91
- async findEntity (profile: OAuthProfile, params: Params) {
92
- const query = await this.getEntityQuery(profile, params);
108
+ async findEntity(profile: OAuthProfile, params: Params) {
109
+ const query = await this.getEntityQuery(profile, params)
93
110
 
94
- debug('findEntity with query', query);
111
+ debug('findEntity with query', query)
95
112
 
96
113
  const result = await this.entityService.find({
97
114
  ...params,
98
115
  query
99
- });
100
- const [ entity = null ] = result.data ? result.data : result;
116
+ })
117
+ const [entity = null] = result.data ? result.data : result
101
118
 
102
- debug('findEntity returning', entity);
119
+ debug('findEntity returning', entity)
103
120
 
104
- return entity;
121
+ return entity
105
122
  }
106
123
 
107
- async createEntity (profile: OAuthProfile, params: Params) {
108
- const data = await this.getEntityData(profile, null, params);
124
+ async createEntity(profile: OAuthProfile, params: Params) {
125
+ const data = await this.getEntityData(profile, null, params)
109
126
 
110
- debug('createEntity with data', data);
127
+ debug('createEntity with data', data)
111
128
 
112
- return this.entityService.create(data, params);
129
+ return this.entityService.create(data, _.omit(params, 'query'))
113
130
  }
114
131
 
115
- async updateEntity (entity: any, profile: OAuthProfile, params: Params) {
116
- const id = entity[this.entityId];
117
- const data = await this.getEntityData(profile, entity, params);
132
+ async updateEntity(entity: any, profile: OAuthProfile, params: Params) {
133
+ const id = entity[this.entityId]
134
+ const data = await this.getEntityData(profile, entity, params)
118
135
 
119
- debug(`updateEntity with id ${id} and data`, data);
136
+ debug(`updateEntity with id ${id} and data`, data)
120
137
 
121
- return this.entityService.patch(id, data, params);
138
+ return this.entityService.patch(id, data, _.omit(params, 'query'))
122
139
  }
123
140
 
124
- async getEntity (result: any, params: Params) {
125
- const { entityService } = this;
126
- const { entityId = (entityService as any).id, entity } = this.configuration;
141
+ async getEntity(result: any, params: Params) {
142
+ const { entityService } = this
143
+ const { entityId = (entityService as any).id, entity } = this.configuration
127
144
 
128
145
  if (!entityId || result[entityId] === undefined) {
129
- throw new NotAuthenticated('Could not get oAuth entity');
146
+ throw new NotAuthenticated('Could not get oAuth entity')
130
147
  }
131
148
 
132
149
  if (!params.provider) {
133
- return result;
150
+ return result
134
151
  }
135
152
 
136
153
  return entityService.get(result[entityId], {
137
- ...params,
154
+ ..._.omit(params, 'query'),
138
155
  [entity]: result
139
- });
156
+ })
140
157
  }
141
158
 
142
- async authenticate (authentication: AuthenticationRequest, originalParams: Params) {
143
- const entity: string = this.configuration.entity;
144
- const { provider, ...params } = originalParams;
145
- const profile = await this.getProfile(authentication, params);
146
- const existingEntity = await this.findEntity(profile, params)
147
- || await this.getCurrentEntity(params);
159
+ async authenticate(authentication: AuthenticationRequest, originalParams: AuthenticationParams) {
160
+ const entity: string = this.configuration.entity
161
+ const { provider, ...params } = originalParams
162
+ const profile = await this.getProfile(authentication, params)
163
+ const existingEntity = (await this.findEntity(profile, params)) || (await this.getCurrentEntity(params))
148
164
 
149
- debug('authenticate with (existing) entity', existingEntity);
165
+ debug('authenticate with (existing) entity', existingEntity)
150
166
 
151
- const authEntity = !existingEntity ? await this.createEntity(profile, params)
152
- : await this.updateEntity(existingEntity, profile, params);
167
+ const authEntity = !existingEntity
168
+ ? await this.createEntity(profile, params)
169
+ : await this.updateEntity(existingEntity, profile, params)
153
170
 
154
171
  return {
155
172
  authentication: { strategy: this.name },
156
173
  [entity]: await this.getEntity(authEntity, originalParams)
157
- };
174
+ }
158
175
  }
159
176
  }
package/src/utils.ts CHANGED
@@ -1,17 +1,123 @@
1
- import { RequestHandler } from 'express';
2
- import { Application } from '@feathersjs/feathers';
1
+ import type { RequestHandler } from 'express'
2
+ import type { Middleware, Application as KoaApplication } from '@feathersjs/koa'
3
+
4
+ import type { ServiceOptions } from '@feathersjs/feathers'
5
+
6
+ import '@feathersjs/koa'
7
+ import '@feathersjs/express'
8
+ import expressCookieSession from 'cookie-session'
9
+ import koaCookieSession from 'koa-session'
10
+
11
+ import { AuthenticationService } from '@feathersjs/authentication'
12
+ import { GrantConfig } from 'grant'
13
+
14
+ import { defaultsDeep, each, omit } from 'lodash'
3
15
 
4
16
  export interface OauthSetupSettings {
5
- authService?: string;
6
- expressSession?: RequestHandler;
7
- linkStrategy: string;
17
+ linkStrategy: string
18
+ authService?: string
19
+ expressSession?: RequestHandler
20
+ koaSession?: Middleware
21
+ }
22
+
23
+ export const getGrantConfig = (service: AuthenticationService): GrantConfig => {
24
+ const {
25
+ app,
26
+ configuration: { oauth }
27
+ } = service
28
+ // Set up all the defaults
29
+ const port = app.get('port')
30
+ let host = app.get('host')
31
+ let protocol = 'https'
32
+
33
+ // Development environments commonly run on HTTP with an extended port
34
+ if (process.env.NODE_ENV !== 'production') {
35
+ protocol = 'http'
36
+ if (String(port) !== '80') {
37
+ host += `:${port}`
38
+ }
39
+ }
40
+
41
+ const grant: GrantConfig = defaultsDeep({}, omit(oauth, ['redirect', 'origins']), {
42
+ defaults: {
43
+ prefix: '/oauth',
44
+ origin: `${protocol}://${host}`,
45
+ transport: 'state',
46
+ response: ['tokens', 'raw', 'profile']
47
+ }
48
+ })
49
+
50
+ const getUrl = (url: string) => {
51
+ const { defaults } = grant
52
+ return `${defaults.origin}${defaults.prefix}/${url}`
53
+ }
54
+
55
+ each(grant, (value, name) => {
56
+ if (name !== 'defaults') {
57
+ value.redirect_uri = value.redirect_uri || getUrl(`${name}/callback`)
58
+ }
59
+ })
60
+
61
+ return grant
62
+ }
63
+
64
+ export const setExpressParams: RequestHandler = (req, res, next) => {
65
+ req.session.destroy ||= () => {
66
+ req.session = null
67
+ }
68
+
69
+ req.feathers = {
70
+ ...req.feathers,
71
+ session: req.session,
72
+ state: res.locals
73
+ }
74
+
75
+ next()
76
+ }
77
+
78
+ export const setKoaParams: Middleware = async (ctx, next) => {
79
+ ctx.session.destroy ||= () => {
80
+ ctx.session = null
81
+ }
82
+
83
+ ctx.feathers = {
84
+ ...ctx.feathers,
85
+ session: ctx.session,
86
+ state: ctx.state
87
+ } as any
88
+
89
+ await next()
8
90
  }
9
91
 
10
- export const getDefaultSettings = (_app: Application, other?: Partial<OauthSetupSettings>) => {
11
- const defaults: OauthSetupSettings = {
12
- linkStrategy: 'jwt',
13
- ...other
14
- };
92
+ export const getServiceOptions = (
93
+ service: AuthenticationService,
94
+ settings: OauthSetupSettings
95
+ ): ServiceOptions => {
96
+ const { secret } = service.configuration
97
+ const koaApp = service.app as KoaApplication
98
+
99
+ if (koaApp.context) {
100
+ koaApp.keys = [secret]
101
+
102
+ const { koaSession = koaCookieSession({ key: 'feathers.oauth' }, koaApp as any) } = settings
15
103
 
16
- return defaults;
17
- };
104
+ return {
105
+ koa: {
106
+ before: [koaSession, setKoaParams]
107
+ }
108
+ }
109
+ }
110
+
111
+ const {
112
+ expressSession = expressCookieSession({
113
+ name: 'feathers.oauth',
114
+ keys: [secret]
115
+ })
116
+ } = settings
117
+
118
+ return {
119
+ express: {
120
+ before: [expressSession, setExpressParams]
121
+ }
122
+ }
123
+ }
package/lib/express.d.ts DELETED
@@ -1,16 +0,0 @@
1
- import { Application } from '@feathersjs/feathers';
2
- import { OauthSetupSettings } from './utils';
3
- declare module 'express-session' {
4
- interface SessionData {
5
- redirect: string;
6
- accessToken: string;
7
- query: {
8
- [key: string]: any;
9
- };
10
- grant: {
11
- [key: string]: any;
12
- };
13
- }
14
- }
15
- declare const _default: (options: OauthSetupSettings) => (feathersApp: Application) => void;
16
- export default _default;
package/lib/express.js DELETED
@@ -1,114 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __rest = (this && this.__rest) || function (s, e) {
12
- var t = {};
13
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
- t[p] = s[p];
15
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
- t[p[i]] = s[p[i]];
19
- }
20
- return t;
21
- };
22
- var __importDefault = (this && this.__importDefault) || function (mod) {
23
- return (mod && mod.__esModule) ? mod : { "default": mod };
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- const grant_1 = __importDefault(require("grant"));
27
- const express_session_1 = __importDefault(require("express-session"));
28
- const commons_1 = require("@feathersjs/commons");
29
- const express_1 = require("@feathersjs/express");
30
- const grantInstance = grant_1.default.express();
31
- const debug = commons_1.createDebug('@feathersjs/authentication-oauth/express');
32
- exports.default = (options) => {
33
- return (feathersApp) => {
34
- const { authService, linkStrategy } = options;
35
- const app = feathersApp;
36
- const config = app.get('grant');
37
- if (!config) {
38
- debug('No grant configuration found, skipping Express oAuth setup');
39
- return;
40
- }
41
- const { prefix } = config.defaults;
42
- const expressSession = options.expressSession || express_session_1.default({
43
- secret: Math.random().toString(36).substring(7),
44
- saveUninitialized: true,
45
- resave: true
46
- });
47
- const grantApp = grantInstance(config);
48
- const authApp = express_1.original();
49
- authApp.use(expressSession);
50
- authApp.get('/:name', (req, _res, next) => {
51
- const _a = req.query, { feathers_token, redirect } = _a, query = __rest(_a, ["feathers_token", "redirect"]);
52
- if (feathers_token) {
53
- debug('Got feathers_token query parameter to link accounts', feathers_token);
54
- req.session.accessToken = feathers_token;
55
- }
56
- req.session.redirect = redirect;
57
- req.session.query = query;
58
- next();
59
- });
60
- authApp.get('/:name/authenticate', (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
61
- const { name } = req.params;
62
- const { accessToken, grant, query = {}, redirect } = req.session;
63
- const service = app.defaultAuthentication(authService);
64
- const [strategy] = service.getStrategies(name);
65
- const params = Object.assign(Object.assign({}, req.feathers), { authStrategies: [name], authentication: accessToken ? {
66
- strategy: linkStrategy,
67
- accessToken
68
- } : null, query,
69
- redirect });
70
- const sendResponse = (data) => __awaiter(void 0, void 0, void 0, function* () {
71
- try {
72
- const redirect = yield strategy.getRedirect(data, params);
73
- if (redirect !== null) {
74
- res.redirect(redirect);
75
- }
76
- else if (data instanceof Error) {
77
- throw data;
78
- }
79
- else {
80
- res.json(data);
81
- }
82
- }
83
- catch (error) {
84
- debug('oAuth error', error);
85
- next(error);
86
- }
87
- });
88
- try {
89
- const payload = config.defaults.transport === 'session' ?
90
- grant.response : req.query;
91
- const authentication = Object.assign({ strategy: name }, payload);
92
- yield new Promise((resolve, reject) => {
93
- if (!req.session.destroy) {
94
- req.session = null;
95
- resolve();
96
- }
97
- req.session.destroy(err => err ? reject(err) : resolve());
98
- });
99
- debug(`Calling ${authService}.create authentication with strategy ${name}`);
100
- const authResult = yield service.create(authentication, params);
101
- debug('Successful oAuth authentication, sending response');
102
- yield sendResponse(authResult);
103
- }
104
- catch (error) {
105
- debug('Received oAuth authentication error', error.stack);
106
- yield sendResponse(error);
107
- }
108
- }));
109
- authApp.use(grantApp);
110
- app.set('grant', grantApp.config);
111
- app.use(prefix, authApp);
112
- };
113
- };
114
- //# sourceMappingURL=express.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"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"}
package/src/express.ts DELETED
@@ -1,127 +0,0 @@
1
- import grant from 'grant';
2
- import session from 'express-session';
3
- import { createDebug } from '@feathersjs/commons';
4
- import { Application } from '@feathersjs/feathers';
5
- import { AuthenticationResult } from '@feathersjs/authentication';
6
- import {
7
- Application as ExpressApplication,
8
- original as originalExpress
9
- } from '@feathersjs/express';
10
- import { OauthSetupSettings } from './utils';
11
- import { OAuthStrategy } from './strategy';
12
-
13
- const grantInstance = grant.express();
14
- const debug = createDebug('@feathersjs/authentication-oauth/express');
15
-
16
- declare module 'express-session' {
17
- interface SessionData {
18
- redirect: string;
19
- accessToken: string;
20
- query: { [key: string]: any };
21
- grant: { [key: string]: any };
22
- }
23
- }
24
-
25
- export default (options: OauthSetupSettings) => {
26
- return (feathersApp: Application) => {
27
- const { authService, linkStrategy } = options;
28
- const app = feathersApp as ExpressApplication;
29
- const config = app.get('grant');
30
-
31
- if (!config) {
32
- debug('No grant configuration found, skipping Express oAuth setup');
33
- return;
34
- }
35
-
36
- const { prefix } = config.defaults;
37
- const expressSession = options.expressSession || session({
38
- secret: Math.random().toString(36).substring(7),
39
- saveUninitialized: true,
40
- resave: true
41
- });
42
- const grantApp = grantInstance(config);
43
- const authApp = originalExpress();
44
-
45
- authApp.use(expressSession);
46
-
47
- authApp.get('/:name', (req, _res, next) => {
48
- const { feathers_token, redirect, ...query } = req.query;
49
-
50
- if (feathers_token) {
51
- debug('Got feathers_token query parameter to link accounts', feathers_token);
52
- req.session.accessToken = feathers_token as string;
53
- }
54
- req.session.redirect = redirect as string;
55
- req.session.query = query;
56
-
57
- next()
58
- });
59
-
60
- authApp.get('/:name/authenticate', async (req, res, next) => {
61
- const { name } = req.params ;
62
- const { accessToken, grant, query = {}, redirect } = req.session;
63
- const service = app.defaultAuthentication(authService);
64
- const [ strategy ] = service.getStrategies(name) as OAuthStrategy[];
65
- const params = {
66
- ...req.feathers,
67
- authStrategies: [ name ],
68
- authentication: accessToken ? {
69
- strategy: linkStrategy,
70
- accessToken
71
- } : null,
72
- query,
73
- redirect
74
- };
75
- const sendResponse = async (data: AuthenticationResult|Error) => {
76
- try {
77
- const redirect = await strategy.getRedirect(data, params);
78
-
79
- if (redirect !== null) {
80
- res.redirect(redirect);
81
- } else if (data instanceof Error) {
82
- throw data;
83
- } else {
84
- res.json(data);
85
- }
86
- } catch (error) {
87
- debug('oAuth error', error);
88
- next(error);
89
- }
90
- };
91
-
92
- try {
93
- const payload = config.defaults.transport === 'session' ?
94
- grant.response : req.query;
95
- const authentication = {
96
- strategy: name,
97
- ...payload
98
- };
99
-
100
- await new Promise<void>((resolve, reject) => {
101
- if (!req.session.destroy) {
102
- req.session = null;
103
- resolve();
104
- }
105
-
106
- req.session.destroy(err => err ? reject(err) : resolve());
107
- });
108
-
109
- debug(`Calling ${authService}.create authentication with strategy ${name}`);
110
-
111
- const authResult = await service.create(authentication, params);
112
-
113
- debug('Successful oAuth authentication, sending response');
114
-
115
- await sendResponse(authResult);
116
- } catch (error) {
117
- debug('Received oAuth authentication error', error.stack);
118
- await sendResponse(error);
119
- }
120
- });
121
-
122
- authApp.use(grantApp);
123
-
124
- app.set('grant', grantApp.config);
125
- app.use(prefix, authApp);
126
- };
127
- };