@feathersjs/authentication-oauth 5.0.0-pre.27 → 5.0.0-pre.29
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 +28 -0
- package/lib/index.d.ts +1 -3
- package/lib/index.js +19 -54
- package/lib/index.js.map +1 -1
- package/lib/service.d.ts +36 -0
- package/lib/service.js +141 -0
- package/lib/service.js.map +1 -0
- package/lib/strategy.js +7 -14
- package/lib/strategy.js.map +1 -1
- package/lib/utils.d.ts +13 -4
- package/lib/utils.js +89 -7
- package/lib/utils.js.map +1 -1
- package/package.json +24 -16
- package/src/index.ts +29 -66
- package/src/service.ts +177 -0
- package/src/strategy.ts +9 -16
- package/src/utils.ts +114 -8
- package/lib/express.d.ts +0 -19
- package/lib/express.js +0 -120
- package/lib/express.js.map +0 -1
- package/src/express.ts +0 -140
package/src/index.ts
CHANGED
|
@@ -1,83 +1,46 @@
|
|
|
1
|
-
import defaultsDeep from 'lodash/defaultsDeep'
|
|
2
|
-
import each from 'lodash/each'
|
|
3
|
-
import omit from 'lodash/omit'
|
|
4
|
-
import { createDebug } from '@feathersjs/commons'
|
|
5
1
|
import { Application } from '@feathersjs/feathers'
|
|
2
|
+
import { createDebug } from '@feathersjs/commons'
|
|
3
|
+
import { resolveDispatch } from '@feathersjs/schema'
|
|
4
|
+
|
|
6
5
|
import { OAuthStrategy, OAuthProfile } from './strategy'
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { redirectHook, OAuthService } from './service'
|
|
7
|
+
import { getServiceOptions, OauthSetupSettings } from './utils'
|
|
9
8
|
|
|
10
9
|
const debug = createDebug('@feathersjs/authentication-oauth')
|
|
11
10
|
|
|
12
11
|
export { OauthSetupSettings, OAuthStrategy, OAuthProfile }
|
|
13
12
|
|
|
14
|
-
export const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
throw new Error(
|
|
19
|
-
'An authentication service must exist before registering @feathersjs/authentication-oauth'
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const { oauth } = service.configuration
|
|
24
|
-
|
|
25
|
-
if (!oauth) {
|
|
26
|
-
debug('No oauth configuration found in authentication configuration. Skipping oAuth setup.')
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const { strategyNames } = service
|
|
31
|
-
|
|
32
|
-
// Set up all the defaults
|
|
33
|
-
const port = app.get('port')
|
|
34
|
-
let host = app.get('host')
|
|
35
|
-
let protocol = 'https'
|
|
13
|
+
export const oauth =
|
|
14
|
+
(settings: Partial<OauthSetupSettings> = {}) =>
|
|
15
|
+
(app: Application) => {
|
|
16
|
+
const authService = app.defaultAuthentication ? app.defaultAuthentication(settings.authService) : null
|
|
36
17
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
host += `:${port}`
|
|
18
|
+
if (!authService) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
'An authentication service must exist before registering @feathersjs/authentication-oauth'
|
|
21
|
+
)
|
|
42
22
|
}
|
|
43
|
-
}
|
|
44
23
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
origin: `${protocol}://${host}`,
|
|
49
|
-
transport: 'session',
|
|
50
|
-
response: ['tokens', 'raw', 'profile']
|
|
24
|
+
if (!authService.configuration.oauth) {
|
|
25
|
+
debug('No oauth configuration found in authentication configuration. Skipping oAuth setup.')
|
|
26
|
+
return
|
|
51
27
|
}
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
const getUrl = (url: string) => {
|
|
55
|
-
const { defaults } = grant
|
|
56
|
-
return `${defaults.origin}${defaults.prefix}/${url}`
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
each(grant, (value, name) => {
|
|
60
|
-
if (name !== 'defaults') {
|
|
61
|
-
value.callback = value.callback || getUrl(`${name}/authenticate`)
|
|
62
|
-
value.redirect_uri = value.redirect_uri || getUrl(`${name}/callback`)
|
|
63
28
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
29
|
+
const oauthOptions = {
|
|
30
|
+
linkStrategy: 'jwt',
|
|
31
|
+
...settings
|
|
68
32
|
}
|
|
69
|
-
|
|
33
|
+
const serviceOptions = getServiceOptions(authService, oauthOptions)
|
|
70
34
|
|
|
71
|
-
|
|
72
|
-
}
|
|
35
|
+
app.use('oauth/:provider', new OAuthService(authService, oauthOptions), serviceOptions)
|
|
73
36
|
|
|
74
|
-
|
|
75
|
-
(settings: Partial<OauthSetupSettings> = {}) =>
|
|
76
|
-
(app: Application) => {
|
|
77
|
-
const options = getDefaultSettings(app, settings)
|
|
37
|
+
const oauthService = app.service('oauth/:provider')
|
|
78
38
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
39
|
+
oauthService.hooks({
|
|
40
|
+
around: { all: [resolveDispatch(), redirectHook()] }
|
|
41
|
+
})
|
|
82
42
|
|
|
83
|
-
|
|
43
|
+
if (typeof oauthService.publish === 'function') {
|
|
44
|
+
app.service('oauth/:provider').publish(() => null)
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/service.ts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { createDebug } from '@feathersjs/commons'
|
|
2
|
+
import { HookContext, NextFunction, Params } from '@feathersjs/feathers'
|
|
3
|
+
import { FeathersError } from '@feathersjs/errors'
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5
|
+
//@ts-ignore
|
|
6
|
+
import Grant from 'grant/lib/grant'
|
|
7
|
+
import { AuthenticationService } from '@feathersjs/authentication'
|
|
8
|
+
import { OAuthStrategy } from './strategy'
|
|
9
|
+
import { getGrantConfig, OauthSetupSettings } from './utils'
|
|
10
|
+
|
|
11
|
+
const debug = createDebug('@feathersjs/authentication-oauth/services')
|
|
12
|
+
|
|
13
|
+
export type GrantResponse = {
|
|
14
|
+
location: string
|
|
15
|
+
session: any
|
|
16
|
+
state: any
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type OAuthParams = Omit<Params, 'route'> & {
|
|
20
|
+
session: any
|
|
21
|
+
state: Record<string, any>
|
|
22
|
+
route: {
|
|
23
|
+
provider: string
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class OAuthError extends FeathersError {
|
|
28
|
+
constructor(message: string, data: any, public location: string) {
|
|
29
|
+
super(message, 'NotAuthenticated', 401, 'not-authenticated', data)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const redirectHook = () => async (context: HookContext, next: NextFunction) => {
|
|
34
|
+
try {
|
|
35
|
+
await next()
|
|
36
|
+
|
|
37
|
+
const { location } = context.result
|
|
38
|
+
|
|
39
|
+
debug(`oAuth redirect to ${location}`)
|
|
40
|
+
|
|
41
|
+
if (location) {
|
|
42
|
+
context.http = {
|
|
43
|
+
...context.http,
|
|
44
|
+
location
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch (error: any) {
|
|
48
|
+
if (error.location) {
|
|
49
|
+
context.http = {
|
|
50
|
+
...context.http,
|
|
51
|
+
location: error.location
|
|
52
|
+
}
|
|
53
|
+
context.result = typeof error.toJSON === 'function' ? error.toJSON() : error
|
|
54
|
+
} else {
|
|
55
|
+
throw error
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export class OAuthService {
|
|
61
|
+
grant: any
|
|
62
|
+
|
|
63
|
+
constructor(public service: AuthenticationService, public settings: OauthSetupSettings) {
|
|
64
|
+
const config = getGrantConfig(service)
|
|
65
|
+
|
|
66
|
+
this.grant = Grant({ config })
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async handler(method: string, params: OAuthParams, body?: any, override?: string): Promise<GrantResponse> {
|
|
70
|
+
const {
|
|
71
|
+
session,
|
|
72
|
+
state,
|
|
73
|
+
query,
|
|
74
|
+
route: { provider }
|
|
75
|
+
} = params
|
|
76
|
+
|
|
77
|
+
const result: GrantResponse = await this.grant({
|
|
78
|
+
params: { provider, override },
|
|
79
|
+
state: state.grant,
|
|
80
|
+
session: session.grant,
|
|
81
|
+
query,
|
|
82
|
+
method,
|
|
83
|
+
body
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
session.grant = result.session
|
|
87
|
+
state.grant = result.state
|
|
88
|
+
|
|
89
|
+
return result
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async authenticate(params: OAuthParams, result: GrantResponse) {
|
|
93
|
+
const name = params.route.provider
|
|
94
|
+
const { linkStrategy, authService } = this.settings
|
|
95
|
+
const { accessToken, grant, query = {}, redirect } = params.session
|
|
96
|
+
const strategy = this.service.getStrategy(name) as OAuthStrategy
|
|
97
|
+
const authParams = {
|
|
98
|
+
...params,
|
|
99
|
+
authStrategies: [name],
|
|
100
|
+
authentication: accessToken
|
|
101
|
+
? {
|
|
102
|
+
strategy: linkStrategy,
|
|
103
|
+
accessToken
|
|
104
|
+
}
|
|
105
|
+
: null,
|
|
106
|
+
query,
|
|
107
|
+
redirect
|
|
108
|
+
}
|
|
109
|
+
const payload = grant?.response || result?.session?.response || result?.state?.response || params.query
|
|
110
|
+
const authentication = {
|
|
111
|
+
strategy: name,
|
|
112
|
+
...payload
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
debug(`Calling ${authService}.create authentication with strategy ${name}`)
|
|
117
|
+
|
|
118
|
+
const authResult = await this.service.create(authentication, authParams)
|
|
119
|
+
|
|
120
|
+
debug('Successful oAuth authentication, sending response')
|
|
121
|
+
|
|
122
|
+
const location = await strategy.getRedirect(authResult, authParams)
|
|
123
|
+
|
|
124
|
+
if (typeof params.session.destroy === 'function') {
|
|
125
|
+
await params.session.destroy()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
...authResult,
|
|
130
|
+
location
|
|
131
|
+
}
|
|
132
|
+
} catch (error: any) {
|
|
133
|
+
const location = await strategy.getRedirect(error, authParams)
|
|
134
|
+
const e = new OAuthError(error.message, error.data, location)
|
|
135
|
+
|
|
136
|
+
if (typeof params.session.destroy === 'function') {
|
|
137
|
+
await params.session.destroy()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
e.stack = error.stack
|
|
141
|
+
throw e
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async find(params: OAuthParams) {
|
|
146
|
+
const { session, query } = params
|
|
147
|
+
const { feathers_token, redirect, ...restQuery } = query
|
|
148
|
+
const handlerParams = {
|
|
149
|
+
...params,
|
|
150
|
+
query: restQuery
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (feathers_token) {
|
|
154
|
+
debug('Got feathers_token query parameter to link accounts', feathers_token)
|
|
155
|
+
session.accessToken = feathers_token
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
session.redirect = redirect
|
|
159
|
+
session.query = restQuery
|
|
160
|
+
|
|
161
|
+
return this.handler('GET', handlerParams, {})
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async get(override: string, params: OAuthParams) {
|
|
165
|
+
const result = await this.handler('GET', params, {}, override)
|
|
166
|
+
|
|
167
|
+
if (override === 'callback') {
|
|
168
|
+
return this.authenticate(params, result)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return result
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async create(data: any, params: OAuthParams) {
|
|
175
|
+
return this.handler('POST', params, data)
|
|
176
|
+
}
|
|
177
|
+
}
|
package/src/strategy.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import querystring from 'querystring'
|
|
5
1
|
import {
|
|
6
2
|
AuthenticationRequest,
|
|
7
3
|
AuthenticationBaseStrategy,
|
|
@@ -11,6 +7,7 @@ import {
|
|
|
11
7
|
import { Params } from '@feathersjs/feathers'
|
|
12
8
|
import { NotAuthenticated } from '@feathersjs/errors'
|
|
13
9
|
import { createDebug, _ } from '@feathersjs/commons'
|
|
10
|
+
import qs from 'qs'
|
|
14
11
|
|
|
15
12
|
const debug = createDebug('@feathersjs/authentication-oauth/strategy')
|
|
16
13
|
|
|
@@ -22,7 +19,7 @@ export interface OAuthProfile {
|
|
|
22
19
|
export class OAuthStrategy extends AuthenticationBaseStrategy {
|
|
23
20
|
get configuration() {
|
|
24
21
|
const { entity, service, entityId, oauth } = this.authentication.configuration
|
|
25
|
-
const config = oauth[this.name]
|
|
22
|
+
const config = oauth[this.name] as any
|
|
26
23
|
|
|
27
24
|
return {
|
|
28
25
|
entity,
|
|
@@ -71,14 +68,14 @@ export class OAuthStrategy extends AuthenticationBaseStrategy {
|
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
async getAllowedOrigin(params?: Params) {
|
|
74
|
-
const { redirect, origins } = this.authentication.configuration.oauth
|
|
71
|
+
const { redirect, origins = this.app.get('origins') } = this.authentication.configuration.oauth
|
|
75
72
|
|
|
76
73
|
if (Array.isArray(origins)) {
|
|
77
|
-
const referer = params?.headers?.referer ||
|
|
74
|
+
const referer = params?.headers?.referer || origins[0]
|
|
78
75
|
const allowedOrigin = origins.find((current) => referer.toLowerCase().startsWith(current.toLowerCase()))
|
|
79
76
|
|
|
80
77
|
if (!allowedOrigin) {
|
|
81
|
-
throw new NotAuthenticated(`Referer "${referer
|
|
78
|
+
throw new NotAuthenticated(`Referer "${referer}" is not allowed.`)
|
|
82
79
|
}
|
|
83
80
|
|
|
84
81
|
return allowedOrigin
|
|
@@ -102,14 +99,10 @@ export class OAuthStrategy extends AuthenticationBaseStrategy {
|
|
|
102
99
|
const separator = redirect.endsWith('?') ? '' : redirect.indexOf('#') !== -1 ? '?' : '#'
|
|
103
100
|
const authResult: AuthenticationResult = data
|
|
104
101
|
const query = authResult.accessToken
|
|
105
|
-
? {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
error: data.message || 'OAuth Authentication not successful'
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return `${redirectUrl}${separator}${querystring.stringify(query)}`
|
|
102
|
+
? { access_token: authResult.accessToken }
|
|
103
|
+
: { error: data.message || 'OAuth Authentication not successful' }
|
|
104
|
+
|
|
105
|
+
return `${redirectUrl}${separator}${qs.stringify(query)}`
|
|
113
106
|
}
|
|
114
107
|
|
|
115
108
|
async findEntity(profile: OAuthProfile, params: Params) {
|
package/src/utils.ts
CHANGED
|
@@ -1,17 +1,123 @@
|
|
|
1
|
-
import { RequestHandler } from 'express'
|
|
2
|
-
import { Application } from '@feathersjs/
|
|
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 {
|
|
17
|
+
linkStrategy: string
|
|
5
18
|
authService?: string
|
|
6
19
|
expressSession?: RequestHandler
|
|
7
|
-
|
|
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
|
|
8
62
|
}
|
|
9
63
|
|
|
10
|
-
export const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
...other
|
|
64
|
+
export const setExpressParams: RequestHandler = (req, res, next) => {
|
|
65
|
+
req.session.destroy ||= () => {
|
|
66
|
+
req.session = null
|
|
14
67
|
}
|
|
15
68
|
|
|
16
|
-
|
|
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()
|
|
90
|
+
}
|
|
91
|
+
|
|
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
|
|
103
|
+
|
|
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
|
+
}
|
|
17
123
|
}
|
package/lib/express.d.ts
DELETED
|
@@ -1,19 +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
|
-
headers: {
|
|
14
|
-
[key: string]: any;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
declare const _default: (options: OauthSetupSettings) => (feathersApp: Application) => void;
|
|
19
|
-
export default _default;
|
package/lib/express.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const grant_1 = __importDefault(require("grant"));
|
|
7
|
-
const express_session_1 = __importDefault(require("express-session"));
|
|
8
|
-
const commons_1 = require("@feathersjs/commons");
|
|
9
|
-
const express_1 = require("@feathersjs/express");
|
|
10
|
-
const grantInstance = grant_1.default.express();
|
|
11
|
-
const debug = (0, commons_1.createDebug)('@feathersjs/authentication-oauth/express');
|
|
12
|
-
exports.default = (options) => {
|
|
13
|
-
return (feathersApp) => {
|
|
14
|
-
const { authService, linkStrategy } = options;
|
|
15
|
-
const app = feathersApp;
|
|
16
|
-
const config = app.get('grant');
|
|
17
|
-
if (!config) {
|
|
18
|
-
debug('No grant configuration found, skipping Express oAuth setup');
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
const { prefix } = config.defaults;
|
|
22
|
-
const expressSession = options.expressSession ||
|
|
23
|
-
(0, express_session_1.default)({
|
|
24
|
-
secret: Math.random().toString(36).substring(7),
|
|
25
|
-
saveUninitialized: true,
|
|
26
|
-
resave: true
|
|
27
|
-
});
|
|
28
|
-
const grantApp = grantInstance(config);
|
|
29
|
-
const authApp = (0, express_1.original)();
|
|
30
|
-
authApp.use(expressSession);
|
|
31
|
-
authApp.get('/:name', (req, _res, next) => {
|
|
32
|
-
const { feathers_token, redirect, ...query } = req.query;
|
|
33
|
-
if (feathers_token) {
|
|
34
|
-
debug('Got feathers_token query parameter to link accounts', feathers_token);
|
|
35
|
-
req.session.accessToken = feathers_token;
|
|
36
|
-
}
|
|
37
|
-
req.session.redirect = redirect;
|
|
38
|
-
req.session.query = query;
|
|
39
|
-
req.session.headers = req.headers;
|
|
40
|
-
if (typeof req.session.save === 'function') {
|
|
41
|
-
req.session.save((err) => {
|
|
42
|
-
if (err) {
|
|
43
|
-
next(`Error storing session: ${err}`);
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
next();
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
next();
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
authApp.get('/:name/authenticate', async (req, res, next) => {
|
|
55
|
-
const { name } = req.params;
|
|
56
|
-
const { accessToken, grant, query = {}, redirect, headers } = req.session;
|
|
57
|
-
const service = app.defaultAuthentication(authService);
|
|
58
|
-
const [strategy] = service.getStrategies(name);
|
|
59
|
-
const params = {
|
|
60
|
-
...req.feathers,
|
|
61
|
-
authStrategies: [name],
|
|
62
|
-
authentication: accessToken
|
|
63
|
-
? {
|
|
64
|
-
strategy: linkStrategy,
|
|
65
|
-
accessToken
|
|
66
|
-
}
|
|
67
|
-
: null,
|
|
68
|
-
query,
|
|
69
|
-
redirect,
|
|
70
|
-
headers
|
|
71
|
-
};
|
|
72
|
-
const sendResponse = async (data) => {
|
|
73
|
-
try {
|
|
74
|
-
const redirect = await strategy.getRedirect(data, params);
|
|
75
|
-
if (redirect !== null) {
|
|
76
|
-
res.redirect(redirect);
|
|
77
|
-
}
|
|
78
|
-
else if (data instanceof Error) {
|
|
79
|
-
throw data;
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
res.json(data);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
debug('oAuth error', error);
|
|
87
|
-
next(error);
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
try {
|
|
91
|
-
const payload = config.defaults.transport === 'session' ? grant.response : req.query;
|
|
92
|
-
const authentication = {
|
|
93
|
-
strategy: name,
|
|
94
|
-
...payload
|
|
95
|
-
};
|
|
96
|
-
await new Promise((resolve, reject) => {
|
|
97
|
-
if (req.session.destroy) {
|
|
98
|
-
req.session.destroy((err) => (err ? reject(err) : resolve()));
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
req.session = null;
|
|
102
|
-
resolve();
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
debug(`Calling ${authService}.create authentication with strategy ${name}`);
|
|
106
|
-
const authResult = await service.create(authentication, params);
|
|
107
|
-
debug('Successful oAuth authentication, sending response');
|
|
108
|
-
await sendResponse(authResult);
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
debug('Received oAuth authentication error', error.stack);
|
|
112
|
-
await sendResponse(error);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
authApp.use(grantApp);
|
|
116
|
-
app.set('grant', grantApp.config);
|
|
117
|
-
app.use(prefix, authApp);
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
//# sourceMappingURL=express.js.map
|
package/lib/express.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"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"}
|