@kaapi/oauth2-auth-design 0.0.13
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/LICENSE +21 -0
- package/README.md +3 -0
- package/lib/flows/auth-code/authorization-route.d.ts +53 -0
- package/lib/flows/auth-code/authorization-route.js +202 -0
- package/lib/flows/auth-code/authorization-route.js.map +1 -0
- package/lib/flows/auth-code/open-id.d.ts +53 -0
- package/lib/flows/auth-code/open-id.js +199 -0
- package/lib/flows/auth-code/open-id.js.map +1 -0
- package/lib/flows/auth-code/token-route.d.ts +35 -0
- package/lib/flows/auth-code/token-route.js +61 -0
- package/lib/flows/auth-code/token-route.js.map +1 -0
- package/lib/flows/auth-code.ts/open-id.d.ts +52 -0
- package/lib/flows/auth-code.ts/open-id.js +169 -0
- package/lib/flows/auth-code.ts/open-id.js.map +1 -0
- package/lib/flows/authentication-code.d.ts +53 -0
- package/lib/flows/authentication-code.js +380 -0
- package/lib/flows/authentication-code.js.map +1 -0
- package/lib/flows/client-credentials.d.ts +55 -0
- package/lib/flows/client-credentials.js +318 -0
- package/lib/flows/client-credentials.js.map +1 -0
- package/lib/flows/common.d.ts +139 -0
- package/lib/flows/common.js +235 -0
- package/lib/flows/common.js.map +1 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +16 -0
- package/lib/index.js.map +1 -0
- package/lib/utils/cache-set.d.ts +12 -0
- package/lib/utils/cache-set.js +35 -0
- package/lib/utils/cache-set.js.map +1 -0
- package/lib/utils/client-auth-methods.d.ts +77 -0
- package/lib/utils/client-auth-methods.js +225 -0
- package/lib/utils/client-auth-methods.js.map +1 -0
- package/lib/utils/in-memory-cache.d.ts +5 -0
- package/lib/utils/in-memory-cache.js +30 -0
- package/lib/utils/in-memory-cache.js.map +1 -0
- package/lib/utils/in-memory-jwks-store.d.ts +12 -0
- package/lib/utils/in-memory-jwks-store.js +46 -0
- package/lib/utils/in-memory-jwks-store.js.map +1 -0
- package/lib/utils/jwks-generator.d.ts +58 -0
- package/lib/utils/jwks-generator.js +141 -0
- package/lib/utils/jwks-generator.js.map +1 -0
- package/lib/utils/jwks-store.d.ts +13 -0
- package/lib/utils/jwks-store.js +3 -0
- package/lib/utils/jwks-store.js.map +1 -0
- package/lib/utils/token-types.d.ts +46 -0
- package/lib/utils/token-types.js +143 -0
- package/lib/utils/token-types.js.map +1 -0
- package/package.json +44 -0
- package/types/overrides.d.ts +14 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-route.js","sourceRoot":"","sources":["../../../src/flows/auth-code/token-route.ts"],"names":[],"mappings":";;;;;AAwCA,MAAa,kBAAkB;IAI3B,MAAM,CAAC,YAAY;QAGf,OAAO,IAAI,yBAAyB,EAAQ,CAAA;IAChD,CAAC;IAKD,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,KAAK,CAAA;IACrB,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAA;IACxB,CAAC;IAED,YACI,IAAY,EACZ,OAAmC;QAEnC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC5B,CAAC;CACJ;AA5BD,gDA4BC;AAcD,MAAa,yBAEX,SAAQ,kBAAwB;IAI9B;QACI,KAAK,CAAC,eAAe,EAAE,CAAO,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;YAC3C,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;gBAC7C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mEAAmE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACrJ,CAAC;YAED,IAAI,CAAC,GAA4E,IAAI,CAAA;YAErF,IAAI,CAAC;gBACD,CAAC,GAAG,MAAM,+BAAA,IAAI,gDAAe,MAAnB,IAAI,EAAgB,KAAK,EAAE,GAAG,CAAC,CAAA;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACX,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC1F,CAAC;YAED,IAAI,CAAC,CAAC;gBAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAEjE,IAAI,OAAO,IAAI,CAAC;gBAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAEhD,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAClC,CAAC,CAAA,CAAC,CAAA;QArBN,2DAA4C;QAuBxC,+BAAA,IAAI,4CAAkB,GAAS,EAAE,wDAAC,OAAA,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAA,GAAA,MAAA,CAAA;IACpE,CAAC;IAED,OAAO,CAAC,IAAe;QACnB,IAAI,IAAI;YACJ,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACrB,OAAO,IAAI,CAAA;IACf,CAAC;IAED,QAAQ,CAAC,OAAmC;QACxC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QACvB,OAAO,IAAI,CAAA;IACf,CAAC;IAED,aAAa,CAAC,OAAqC;QAC/C,+BAAA,IAAI,4CAAkB,OAAO,MAAA,CAAA;QAC7B,OAAO,IAAI,CAAA;IACf,CAAC;CACJ;AA7CD,8DA6CC;;AAED,qBAAqB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SecuritySchemeObject } from '@novice1/api-doc-generator/lib/generators/openapi/definitions';
|
|
2
|
+
import { OAuth2Util } from '@novice1/api-doc-generator';
|
|
3
|
+
import { OAuth2AuthorizationCode, OAuth2AuthorizationCodeArg } from '../authentication-code';
|
|
4
|
+
import { KaapiTools, Lifecycle, ReqRef, Request, ReqRefDefaults, ResponseToolkit } from '@kaapi/kaapi';
|
|
5
|
+
import { JWKS } from '../../utils/jwks-store';
|
|
6
|
+
export declare class OpenIDAuthUtil extends OAuth2Util {
|
|
7
|
+
toOpenAPI(): Record<string, SecuritySchemeObject>;
|
|
8
|
+
}
|
|
9
|
+
export interface OpenIDJWKSParams {
|
|
10
|
+
jwks: JWKS;
|
|
11
|
+
}
|
|
12
|
+
export type OpenIDJWKSHandler<Refs extends ReqRef = ReqRefDefaults, R extends Lifecycle.ReturnValue<any> = Lifecycle.ReturnValue<Refs>> = (params: OpenIDJWKSParams, request: Request<Refs>, h: ResponseToolkit<Refs>) => R;
|
|
13
|
+
export interface IOpenIDJWKSRoute<Refs extends ReqRef = ReqRefDefaults> {
|
|
14
|
+
path: string;
|
|
15
|
+
handler?: OpenIDJWKSHandler<Refs>;
|
|
16
|
+
}
|
|
17
|
+
export declare class OpenIDJWKSRoute<Refs extends ReqRef = ReqRefDefaults> implements IOpenIDJWKSRoute<Refs> {
|
|
18
|
+
protected _path: string;
|
|
19
|
+
protected _handler: OpenIDJWKSHandler<Refs> | undefined;
|
|
20
|
+
get path(): string;
|
|
21
|
+
get handler(): OpenIDJWKSHandler<Refs, Lifecycle.ReturnValue<Refs>> | undefined;
|
|
22
|
+
constructor(path: string, handler?: OpenIDJWKSHandler<Refs>);
|
|
23
|
+
}
|
|
24
|
+
export type OpenIDUserInfoHandler<Refs extends ReqRef = ReqRefDefaults, R extends Lifecycle.ReturnValue<any> = Lifecycle.ReturnValue<Refs>> = (request: Request<Refs>, h: ResponseToolkit<Refs>) => R;
|
|
25
|
+
export interface IOpenIDUserInfoRoute<Refs extends ReqRef = ReqRefDefaults> {
|
|
26
|
+
path: string;
|
|
27
|
+
handler?: OpenIDUserInfoHandler<Refs>;
|
|
28
|
+
}
|
|
29
|
+
export declare class OpenIDUserInfoRoute<Refs extends ReqRef = ReqRefDefaults> implements IOpenIDUserInfoRoute<Refs> {
|
|
30
|
+
protected _path: string;
|
|
31
|
+
protected _handler: OpenIDUserInfoHandler<Refs>;
|
|
32
|
+
get path(): string;
|
|
33
|
+
get handler(): OpenIDUserInfoHandler<Refs, Lifecycle.ReturnValue<Refs>>;
|
|
34
|
+
constructor(path: string, handler: OpenIDUserInfoHandler<Refs>);
|
|
35
|
+
}
|
|
36
|
+
export interface OpenIDAuthDesignArg extends OAuth2AuthorizationCodeArg {
|
|
37
|
+
jwksRoute: OpenIDJWKSRoute<any>;
|
|
38
|
+
userInfoRoute: OpenIDUserInfoRoute<any>;
|
|
39
|
+
/**
|
|
40
|
+
* Override the configuration served at /.well-known/openid-configuration
|
|
41
|
+
*/
|
|
42
|
+
openidConfiguration?: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
export declare class OpenIDAuthDesign extends OAuth2AuthorizationCode {
|
|
45
|
+
protected jwksRoute: OpenIDJWKSRoute<any>;
|
|
46
|
+
protected userInfoRoute: OpenIDUserInfoRoute<any>;
|
|
47
|
+
protected openidConfiguration: Record<string, unknown>;
|
|
48
|
+
constructor(params: OpenIDAuthDesignArg);
|
|
49
|
+
getScopes(): Record<string, string>;
|
|
50
|
+
integrateHook(t: KaapiTools): void;
|
|
51
|
+
docs(): OAuth2Util;
|
|
52
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenIDAuthDesign = exports.OpenIDUserInfoRoute = exports.OpenIDJWKSRoute = exports.OpenIDAuthUtil = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const api_doc_generator_1 = require("@novice1/api-doc-generator");
|
|
6
|
+
const authentication_code_1 = require("../authentication-code");
|
|
7
|
+
//#region OpenIDAuthUtil
|
|
8
|
+
class OpenIDAuthUtil extends api_doc_generator_1.OAuth2Util {
|
|
9
|
+
toOpenAPI() {
|
|
10
|
+
const host = this.getHost();
|
|
11
|
+
return {
|
|
12
|
+
[this.securitySchemeName]: {
|
|
13
|
+
type: 'openIdConnect',
|
|
14
|
+
openIdConnectUrl: `${host || ''}/.well-known/openid-configuration`
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.OpenIDAuthUtil = OpenIDAuthUtil;
|
|
20
|
+
class OpenIDJWKSRoute {
|
|
21
|
+
get path() {
|
|
22
|
+
return this._path;
|
|
23
|
+
}
|
|
24
|
+
get handler() {
|
|
25
|
+
return this._handler;
|
|
26
|
+
}
|
|
27
|
+
constructor(path, handler) {
|
|
28
|
+
this._path = path;
|
|
29
|
+
this._handler = handler;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.OpenIDJWKSRoute = OpenIDJWKSRoute;
|
|
33
|
+
class OpenIDUserInfoRoute {
|
|
34
|
+
get path() {
|
|
35
|
+
return this._path;
|
|
36
|
+
}
|
|
37
|
+
get handler() {
|
|
38
|
+
return this._handler;
|
|
39
|
+
}
|
|
40
|
+
constructor(path, handler) {
|
|
41
|
+
this._path = path;
|
|
42
|
+
this._handler = handler;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.OpenIDUserInfoRoute = OpenIDUserInfoRoute;
|
|
46
|
+
class OpenIDAuthDesign extends authentication_code_1.OAuth2AuthorizationCode {
|
|
47
|
+
constructor(params) {
|
|
48
|
+
const { strategyName, openidConfiguration, jwksRoute, userInfoRoute } = params, props = tslib_1.__rest(params, ["strategyName", "openidConfiguration", "jwksRoute", "userInfoRoute"]);
|
|
49
|
+
super(props);
|
|
50
|
+
this.openidConfiguration = {};
|
|
51
|
+
this.pkce = true;
|
|
52
|
+
this.strategyName = strategyName || 'open-id-auth-design';
|
|
53
|
+
this.jwksRoute = jwksRoute;
|
|
54
|
+
this.userInfoRoute = userInfoRoute;
|
|
55
|
+
if (openidConfiguration)
|
|
56
|
+
this.openidConfiguration = openidConfiguration;
|
|
57
|
+
}
|
|
58
|
+
getScopes() {
|
|
59
|
+
let scopes = {
|
|
60
|
+
openid: 'enable OpenID Connect'
|
|
61
|
+
};
|
|
62
|
+
if (this.scopes) {
|
|
63
|
+
if ('openid' in this.scopes) {
|
|
64
|
+
scopes = this.scopes;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
scopes = Object.assign(Object.assign({}, this.scopes), scopes);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return scopes;
|
|
71
|
+
}
|
|
72
|
+
integrateHook(t) {
|
|
73
|
+
var _a;
|
|
74
|
+
super.integrateHook(t);
|
|
75
|
+
const docs = this.docs();
|
|
76
|
+
const challengeAlgo = docs.getChallengeAlgorithm();
|
|
77
|
+
const host = ((_a = t.postman) === null || _a === void 0 ? void 0 : _a.getHost()[0]) || '';
|
|
78
|
+
t.route({
|
|
79
|
+
path: '/.well-known/openid-configuration',
|
|
80
|
+
method: 'GET',
|
|
81
|
+
options: {
|
|
82
|
+
plugins: {
|
|
83
|
+
kaapi: {
|
|
84
|
+
docs: false
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
handler: () => {
|
|
89
|
+
return Object.assign({ issuer: host, authorization_endpoint: `${host}${this.authorizationRoute.path}`, token_endpoint: `${host}${this.tokenRoute.path}`, userinfo_endpoint: `${host}${this.userInfoRoute.path}`, jwks_uri: `${host}${this.jwksRoute.path}`, claims_supported: [
|
|
90
|
+
'aud',
|
|
91
|
+
'exp',
|
|
92
|
+
'iat',
|
|
93
|
+
'iss',
|
|
94
|
+
'sub'
|
|
95
|
+
], grant_types_supported: [
|
|
96
|
+
'authorization_code'
|
|
97
|
+
], response_types_supported: [
|
|
98
|
+
'code',
|
|
99
|
+
'token',
|
|
100
|
+
'code token',
|
|
101
|
+
'code token id_token'
|
|
102
|
+
], scopes_supported: Object.keys(docs.getScopes()), subject_types_supported: [
|
|
103
|
+
'public'
|
|
104
|
+
], id_token_signing_alg_values_supported: [
|
|
105
|
+
'RS256'
|
|
106
|
+
], code_challenge_methods_supported: challengeAlgo ? [
|
|
107
|
+
challengeAlgo
|
|
108
|
+
] : [], token_endpoint_auth_methods_supported: [
|
|
109
|
+
'client_secret_post'
|
|
110
|
+
] }, this.openidConfiguration);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
t.route({
|
|
114
|
+
path: this.jwksRoute.path,
|
|
115
|
+
method: 'GET',
|
|
116
|
+
options: {
|
|
117
|
+
plugins: {
|
|
118
|
+
kaapi: {
|
|
119
|
+
docs: false
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
handler: (req, h) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
124
|
+
const jwks = yield this.jwksGenerator.get();
|
|
125
|
+
if (this.jwksRoute.handler) {
|
|
126
|
+
return this.jwksRoute.handler({
|
|
127
|
+
jwks
|
|
128
|
+
}, req, h);
|
|
129
|
+
}
|
|
130
|
+
return jwks;
|
|
131
|
+
})
|
|
132
|
+
});
|
|
133
|
+
t.route({
|
|
134
|
+
path: this.userInfoRoute.path,
|
|
135
|
+
method: 'GET',
|
|
136
|
+
options: {
|
|
137
|
+
auth: {
|
|
138
|
+
strategy: this.strategyName,
|
|
139
|
+
mode: 'required'
|
|
140
|
+
},
|
|
141
|
+
plugins: {
|
|
142
|
+
kaapi: {
|
|
143
|
+
docs: false
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
handler: this.userInfoRoute.handler.bind(this.userInfoRoute)
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
docs() {
|
|
151
|
+
var _a;
|
|
152
|
+
const docs = new OpenIDAuthUtil(this.strategyName)
|
|
153
|
+
.setGrantType(this.isWithPkce() ? api_doc_generator_1.GrantType.authorizationCodeWithPkce : api_doc_generator_1.GrantType.authorizationCode)
|
|
154
|
+
.setScopes(this.getScopes())
|
|
155
|
+
.setAuthUrl(this.authorizationRoute.path)
|
|
156
|
+
.setAccessTokenUrl(this.tokenRoute.path || '')
|
|
157
|
+
.setChallengeAlgorithm(api_doc_generator_1.ChallengeAlgorithm.S256);
|
|
158
|
+
if ((_a = this.refreshTokenRoute) === null || _a === void 0 ? void 0 : _a.path) {
|
|
159
|
+
docs.setRefreshUrl(this.refreshTokenRoute.path);
|
|
160
|
+
}
|
|
161
|
+
if (this.description) {
|
|
162
|
+
docs.setDescription(this.description);
|
|
163
|
+
}
|
|
164
|
+
return docs;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.OpenIDAuthDesign = OpenIDAuthDesign;
|
|
168
|
+
//#endregion OpenIDAuthDesign
|
|
169
|
+
//# sourceMappingURL=open-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-id.js","sourceRoot":"","sources":["../../../src/flows/auth-code.ts/open-id.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { KaapiTools } from '@kaapi/kaapi';
|
|
2
|
+
import { OAuth2Util } from '@novice1/api-doc-generator';
|
|
3
|
+
import { IOAuth2RefreshTokenRoute, OAuth2WithJWKSAuthDesign, OAuth2AuthOptions } from './common';
|
|
4
|
+
import { JWKSStore } from '../utils/jwks-store';
|
|
5
|
+
import { IOAuth2ACAuthorizationRoute } from './auth-code/authorization-route';
|
|
6
|
+
import { IOAuth2ACTokenRoute } from './auth-code/token-route';
|
|
7
|
+
export interface OAuth2AuthorizationCodeArg {
|
|
8
|
+
authorizationRoute: IOAuth2ACAuthorizationRoute<any, any>;
|
|
9
|
+
tokenRoute: IOAuth2ACTokenRoute<any>;
|
|
10
|
+
refreshTokenRoute?: IOAuth2RefreshTokenRoute<any>;
|
|
11
|
+
options?: OAuth2AuthOptions;
|
|
12
|
+
strategyName?: string;
|
|
13
|
+
jwksStore?: JWKSStore;
|
|
14
|
+
}
|
|
15
|
+
export declare class OAuth2AuthorizationCode extends OAuth2WithJWKSAuthDesign {
|
|
16
|
+
protected strategyName: string;
|
|
17
|
+
protected description?: string;
|
|
18
|
+
protected scopes?: Record<string, string>;
|
|
19
|
+
protected options: OAuth2AuthOptions;
|
|
20
|
+
protected pkce: boolean;
|
|
21
|
+
protected clientAuthenticationMethods: {
|
|
22
|
+
header: boolean;
|
|
23
|
+
body: boolean;
|
|
24
|
+
};
|
|
25
|
+
protected authorizationRoute: IOAuth2ACAuthorizationRoute<any, any>;
|
|
26
|
+
protected tokenRoute: IOAuth2ACTokenRoute<any>;
|
|
27
|
+
protected refreshTokenRoute?: IOAuth2RefreshTokenRoute<any>;
|
|
28
|
+
constructor({ authorizationRoute, tokenRoute, refreshTokenRoute, options, strategyName, jwksStore }: OAuth2AuthorizationCodeArg);
|
|
29
|
+
withPkce(): this;
|
|
30
|
+
withoutPkce(): this;
|
|
31
|
+
isWithPkce(): boolean;
|
|
32
|
+
noneAuthenticationMethod(): this;
|
|
33
|
+
setDescription(description: string): this;
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @param scopes The scopes of the access request.
|
|
37
|
+
* A map between the scope name and a short description for it. The map MAY be empty.
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
setScopes(scopes: Record<string, string>): this;
|
|
41
|
+
getScopes(): Record<string, string> | undefined;
|
|
42
|
+
getStrategyName(): string;
|
|
43
|
+
getDescription(): string | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Returns the schema used for the documentation
|
|
46
|
+
*/
|
|
47
|
+
docs(): OAuth2Util;
|
|
48
|
+
/**
|
|
49
|
+
* Where authentication schemes and strategies are registered.
|
|
50
|
+
*/
|
|
51
|
+
integrateStrategy(t: KaapiTools): void;
|
|
52
|
+
integrateHook(t: KaapiTools): void;
|
|
53
|
+
}
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OAuth2AuthorizationCode = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const api_doc_generator_1 = require("@novice1/api-doc-generator");
|
|
6
|
+
const boom_1 = tslib_1.__importDefault(require("@hapi/boom"));
|
|
7
|
+
const hoek_1 = tslib_1.__importDefault(require("@hapi/hoek"));
|
|
8
|
+
const common_1 = require("./common");
|
|
9
|
+
const jwks_generator_1 = require("../utils/jwks-generator");
|
|
10
|
+
class OAuth2AuthorizationCode extends common_1.OAuth2WithJWKSAuthDesign {
|
|
11
|
+
constructor({ authorizationRoute, tokenRoute, refreshTokenRoute, options, strategyName, jwksStore }) {
|
|
12
|
+
super(jwksStore);
|
|
13
|
+
this.pkce = false;
|
|
14
|
+
this.clientAuthenticationMethods = {
|
|
15
|
+
header: false,
|
|
16
|
+
body: false
|
|
17
|
+
};
|
|
18
|
+
this.authorizationRoute = authorizationRoute;
|
|
19
|
+
this.tokenRoute = tokenRoute;
|
|
20
|
+
this.refreshTokenRoute = refreshTokenRoute;
|
|
21
|
+
this.strategyName = strategyName || 'oauth2-authorization-code';
|
|
22
|
+
this.options = options ? Object.assign({}, options) : {};
|
|
23
|
+
}
|
|
24
|
+
withPkce() {
|
|
25
|
+
this.pkce = true;
|
|
26
|
+
return super.noneAuthenticationMethod();
|
|
27
|
+
}
|
|
28
|
+
withoutPkce() {
|
|
29
|
+
this.pkce = false;
|
|
30
|
+
this._clientAuthMethods.none = undefined;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
isWithPkce() {
|
|
34
|
+
return this.pkce;
|
|
35
|
+
}
|
|
36
|
+
noneAuthenticationMethod() {
|
|
37
|
+
return this.withPkce();
|
|
38
|
+
}
|
|
39
|
+
setDescription(description) {
|
|
40
|
+
this.description = description;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
* @param scopes The scopes of the access request.
|
|
46
|
+
* A map between the scope name and a short description for it. The map MAY be empty.
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
setScopes(scopes) {
|
|
50
|
+
this.scopes = scopes;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
getScopes() {
|
|
54
|
+
return this.scopes;
|
|
55
|
+
}
|
|
56
|
+
getStrategyName() {
|
|
57
|
+
return this.strategyName;
|
|
58
|
+
}
|
|
59
|
+
getDescription() {
|
|
60
|
+
return this.description;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns the schema used for the documentation
|
|
64
|
+
*/
|
|
65
|
+
docs() {
|
|
66
|
+
var _a;
|
|
67
|
+
const docs = new api_doc_generator_1.OAuth2Util(this.strategyName)
|
|
68
|
+
.setGrantType(this.isWithPkce() ? api_doc_generator_1.GrantType.authorizationCodeWithPkce : api_doc_generator_1.GrantType.authorizationCode)
|
|
69
|
+
.setScopes(this.getScopes() || {})
|
|
70
|
+
.setAuthUrl(this.authorizationRoute.path)
|
|
71
|
+
.setAccessTokenUrl(this.tokenRoute.path || '');
|
|
72
|
+
const supported = this.getTokenEndpointAuthMethods();
|
|
73
|
+
if (supported.includes('client_secret_post')) {
|
|
74
|
+
docs.setChallengeAlgorithm(api_doc_generator_1.ClientAuthentication.body);
|
|
75
|
+
}
|
|
76
|
+
else if (supported.includes('client_secret_basic')) {
|
|
77
|
+
docs.setChallengeAlgorithm(api_doc_generator_1.ClientAuthentication.header);
|
|
78
|
+
}
|
|
79
|
+
if ((_a = this.refreshTokenRoute) === null || _a === void 0 ? void 0 : _a.path) {
|
|
80
|
+
docs.setRefreshUrl(this.refreshTokenRoute.path);
|
|
81
|
+
}
|
|
82
|
+
if (this.description) {
|
|
83
|
+
docs.setDescription(this.description);
|
|
84
|
+
}
|
|
85
|
+
return docs;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Where authentication schemes and strategies are registered.
|
|
89
|
+
*/
|
|
90
|
+
integrateStrategy(t) {
|
|
91
|
+
const tokenTypePrefix = this.tokenType;
|
|
92
|
+
const tokenTypeInstance = this._tokenType;
|
|
93
|
+
t.scheme(this.strategyName, (_server, options) => {
|
|
94
|
+
return {
|
|
95
|
+
authenticate(request, h) {
|
|
96
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
var _a;
|
|
98
|
+
const settings = hoek_1.default.applyToDefaults({}, options || {});
|
|
99
|
+
const authorization = request.raw.req.headers.authorization;
|
|
100
|
+
const authSplit = authorization ? authorization.split(/\s+/) : ['', ''];
|
|
101
|
+
const tokenType = authSplit[0];
|
|
102
|
+
let token = authSplit[1];
|
|
103
|
+
if (tokenType.toLowerCase() !== tokenTypePrefix.toLowerCase()) {
|
|
104
|
+
token = '';
|
|
105
|
+
return boom_1.default.unauthorized(null, tokenTypePrefix);
|
|
106
|
+
}
|
|
107
|
+
if (!(yield tokenTypeInstance.isValid(request, token)).isValid) {
|
|
108
|
+
return boom_1.default.unauthorized(null, tokenTypePrefix);
|
|
109
|
+
}
|
|
110
|
+
if (settings.validate) {
|
|
111
|
+
try {
|
|
112
|
+
const result = yield ((_a = settings.validate) === null || _a === void 0 ? void 0 : _a.call(settings, request, token, h));
|
|
113
|
+
if (result && 'isAuth' in result) {
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
if (result && 'isBoom' in result) {
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
if (result) {
|
|
120
|
+
const { isValid, credentials, artifacts, message } = result;
|
|
121
|
+
if (isValid && credentials) {
|
|
122
|
+
return h.authenticated({ credentials, artifacts });
|
|
123
|
+
}
|
|
124
|
+
if (message) {
|
|
125
|
+
return h.unauthenticated(boom_1.default.unauthorized(message, tokenTypePrefix), {
|
|
126
|
+
credentials: credentials || {},
|
|
127
|
+
artifacts
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
return boom_1.default.internal(err instanceof Error ? err : `${err}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return boom_1.default.unauthorized(null, tokenTypePrefix);
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
t.strategy(this.strategyName, this.strategyName, this.options);
|
|
142
|
+
}
|
|
143
|
+
integrateHook(t) {
|
|
144
|
+
var _a;
|
|
145
|
+
const hasOpenIDScope = () => { var _a; return typeof ((_a = this.getScopes()) === null || _a === void 0 ? void 0 : _a['openid']) != 'undefined'; };
|
|
146
|
+
const tokenTypeInstance = this._tokenType;
|
|
147
|
+
const supported = this.getTokenEndpointAuthMethods();
|
|
148
|
+
const authMethodsInstances = this.clientAuthMethods;
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
150
|
+
const routesOptions = {
|
|
151
|
+
plugins: {
|
|
152
|
+
kaapi: {
|
|
153
|
+
docs: false
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
t
|
|
158
|
+
.route({
|
|
159
|
+
options: routesOptions,
|
|
160
|
+
path: this.authorizationRoute.path,
|
|
161
|
+
method: ['GET', 'POST'],
|
|
162
|
+
handler: (req, h) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
163
|
+
// validating query
|
|
164
|
+
if (req.query.client_id && typeof req.query.client_id === 'string' &&
|
|
165
|
+
req.query.response_type === 'code' &&
|
|
166
|
+
req.query.redirect_uri && typeof req.query.redirect_uri === 'string') {
|
|
167
|
+
const params = {
|
|
168
|
+
clientId: req.query.client_id,
|
|
169
|
+
redirectUri: req.query.redirect_uri,
|
|
170
|
+
responseType: req.query.response_type
|
|
171
|
+
};
|
|
172
|
+
if (req.query.scope && typeof req.query.scope === 'string') {
|
|
173
|
+
params.scope = req.query.scope;
|
|
174
|
+
}
|
|
175
|
+
if (req.query.state && typeof req.query.state === 'string') {
|
|
176
|
+
params.state = req.query.state;
|
|
177
|
+
}
|
|
178
|
+
if (req.query.code_challenge && typeof req.query.code_challenge === 'string') {
|
|
179
|
+
params.codeChallenge = req.query.code_challenge;
|
|
180
|
+
}
|
|
181
|
+
if (req.query.nonce && typeof req.query.nonce === 'string') {
|
|
182
|
+
params.nonce = req.query.nonce;
|
|
183
|
+
}
|
|
184
|
+
if (req.method.toLowerCase() === 'get') {
|
|
185
|
+
return this.authorizationRoute.handler(params, req, h);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
return this.authorizationRoute.postHandler(params, req, h);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
let errorDescription = '';
|
|
193
|
+
if (!(req.query.client_id && typeof req.query.client_id === 'string')) {
|
|
194
|
+
errorDescription = 'Request was missing the \'client_id\' parameter.';
|
|
195
|
+
}
|
|
196
|
+
else if (!(req.query.response_type === 'code')) {
|
|
197
|
+
errorDescription = `Request does not support the 'response_type' '${req.query.response_type}'.`;
|
|
198
|
+
}
|
|
199
|
+
else if (!(req.query.redirect_uri && typeof req.query.redirect_uri === 'string')) {
|
|
200
|
+
errorDescription = 'Request was missing the \'redirect_uri\' parameter.';
|
|
201
|
+
}
|
|
202
|
+
return h.response({ error: 'invalid_request', error_description: errorDescription }).code(400);
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
.route({
|
|
207
|
+
options: routesOptions,
|
|
208
|
+
path: this.tokenRoute.path,
|
|
209
|
+
method: 'POST',
|
|
210
|
+
handler: (req, h) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
211
|
+
var _a, _b;
|
|
212
|
+
// Grant validation
|
|
213
|
+
const supportedGrants = ['authorization_code'];
|
|
214
|
+
if (this.tokenRoute.path == ((_a = this.refreshTokenRoute) === null || _a === void 0 ? void 0 : _a.path)) {
|
|
215
|
+
supportedGrants.push('refresh_token');
|
|
216
|
+
}
|
|
217
|
+
if (!(typeof req.payload.grant_type === 'string' && supportedGrants.includes(req.payload.grant_type))) {
|
|
218
|
+
return h.response({ error: 'unsupported_grant_type', error_description: `Request does not support the 'grant_type' '${req.payload.grant_type}'.` }).code(400);
|
|
219
|
+
}
|
|
220
|
+
// Client authentication is present?
|
|
221
|
+
const { clientId, clientSecret, error, errorDescription } = yield this._extractClientParams(req, authMethodsInstances, supported);
|
|
222
|
+
if (error) {
|
|
223
|
+
return h.response({ error: error, error_description: errorDescription || undefined }).code(400);
|
|
224
|
+
}
|
|
225
|
+
if (!clientId) {
|
|
226
|
+
return h
|
|
227
|
+
.response({
|
|
228
|
+
error: 'invalid_request',
|
|
229
|
+
error_description: `Supported token endpoint authentication methods: ${supported.join(', ')}`
|
|
230
|
+
}).code(400);
|
|
231
|
+
}
|
|
232
|
+
if (clientId &&
|
|
233
|
+
req.payload.code && typeof req.payload.code === 'string' &&
|
|
234
|
+
req.payload.grant_type === 'authorization_code') {
|
|
235
|
+
const params = {
|
|
236
|
+
clientId,
|
|
237
|
+
grantType: req.payload.grant_type,
|
|
238
|
+
code: req.payload.code,
|
|
239
|
+
ttl: this.jwksGenerator.ttl,
|
|
240
|
+
createIDToken: hasOpenIDScope() ? ((payload) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
241
|
+
var _a;
|
|
242
|
+
return yield (0, jwks_generator_1.createIDToken)(this.jwksGenerator, Object.assign({ aud: clientId, iss: ((_a = t.postman) === null || _a === void 0 ? void 0 : _a.getHost()[0]) || '' }, payload));
|
|
243
|
+
})) : undefined
|
|
244
|
+
};
|
|
245
|
+
if (clientSecret) {
|
|
246
|
+
params.clientSecret = clientSecret;
|
|
247
|
+
}
|
|
248
|
+
if (req.payload.code_verifier && typeof req.payload.code_verifier === 'string') {
|
|
249
|
+
params.codeVerifier = req.payload.code_verifier;
|
|
250
|
+
}
|
|
251
|
+
if (req.payload.redirect_uri && typeof req.payload.redirect_uri === 'string') {
|
|
252
|
+
params.redirectUri = req.payload.redirect_uri;
|
|
253
|
+
}
|
|
254
|
+
const ttR = tokenTypeInstance.isValidTokenRequest ? (yield tokenTypeInstance.isValidTokenRequest(req)) : { isValid: true };
|
|
255
|
+
if (!ttR.isValid) {
|
|
256
|
+
return h.response({ error: 'invalid_request', error_description: ttR.message || '' }).code(400);
|
|
257
|
+
}
|
|
258
|
+
return this.tokenRoute.handler(params, req, h);
|
|
259
|
+
}
|
|
260
|
+
else if (this.tokenRoute.path == ((_b = this.refreshTokenRoute) === null || _b === void 0 ? void 0 : _b.path) &&
|
|
261
|
+
req.payload.grant_type === 'refresh_token') {
|
|
262
|
+
const hasRefreshToken = req.payload.refresh_token && typeof req.payload.refresh_token === 'string';
|
|
263
|
+
if (clientId &&
|
|
264
|
+
hasRefreshToken) {
|
|
265
|
+
const params = {
|
|
266
|
+
clientId,
|
|
267
|
+
grantType: req.payload.grant_type,
|
|
268
|
+
refreshToken: `${req.payload.refresh_token}`,
|
|
269
|
+
ttl: this.jwksGenerator.ttl,
|
|
270
|
+
createIDToken: hasOpenIDScope() ? ((payload) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
271
|
+
var _a;
|
|
272
|
+
return yield (0, jwks_generator_1.createIDToken)(this.jwksGenerator, Object.assign({ aud: clientId, iss: ((_a = t.postman) === null || _a === void 0 ? void 0 : _a.getHost()[0]) || '' }, payload));
|
|
273
|
+
})) : undefined
|
|
274
|
+
};
|
|
275
|
+
if (clientSecret) {
|
|
276
|
+
params.clientSecret = clientSecret;
|
|
277
|
+
}
|
|
278
|
+
if (req.payload.scope && typeof req.payload.scope === 'string') {
|
|
279
|
+
params.scope = req.payload.scope;
|
|
280
|
+
}
|
|
281
|
+
return this.refreshTokenRoute.handler(params, req, h);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
let error = 'unauthorized_client';
|
|
285
|
+
let errorDescription = '';
|
|
286
|
+
if (!clientId) {
|
|
287
|
+
error = 'invalid_request';
|
|
288
|
+
errorDescription = 'Request was missing the \'client_id\' parameter.';
|
|
289
|
+
}
|
|
290
|
+
else if (!(req.payload.refresh_token && typeof req.payload.refresh_token === 'string')) {
|
|
291
|
+
error = 'invalid_request';
|
|
292
|
+
errorDescription = 'Request was missing the \'refresh_token\' parameter.';
|
|
293
|
+
}
|
|
294
|
+
return h.response({ error, error_description: errorDescription }).code(400);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
let error = 'unauthorized_client';
|
|
299
|
+
let errorDescription = '';
|
|
300
|
+
if (!clientId) {
|
|
301
|
+
error = 'invalid_request';
|
|
302
|
+
errorDescription = 'Request was missing the \'client_id\' parameter.';
|
|
303
|
+
}
|
|
304
|
+
else if (!(req.payload.code && typeof req.payload.code === 'string')) {
|
|
305
|
+
error = 'invalid_request';
|
|
306
|
+
errorDescription = 'Request was missing the \'code\' parameter.';
|
|
307
|
+
}
|
|
308
|
+
return h.response({ error, error_description: errorDescription }).code(400);
|
|
309
|
+
}
|
|
310
|
+
})
|
|
311
|
+
});
|
|
312
|
+
// refreshToken
|
|
313
|
+
if (((_a = this.refreshTokenRoute) === null || _a === void 0 ? void 0 : _a.path) && this.refreshTokenRoute.path != this.tokenRoute.path) {
|
|
314
|
+
t.route({
|
|
315
|
+
options: routesOptions,
|
|
316
|
+
path: this.refreshTokenRoute.path,
|
|
317
|
+
method: 'POST',
|
|
318
|
+
handler: (req, h) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
319
|
+
var _a;
|
|
320
|
+
// Grant validation
|
|
321
|
+
const supportedGrants = ['refresh_token'];
|
|
322
|
+
if (!(typeof req.payload.grant_type === 'string' && supportedGrants.includes(req.payload.grant_type))) {
|
|
323
|
+
return h.response({ error: 'unsupported_grant_type', error_description: `Request does not support the 'grant_type' '${req.payload.grant_type}'.` }).code(400);
|
|
324
|
+
}
|
|
325
|
+
// Client authentication is present?
|
|
326
|
+
const { clientId, clientSecret, error, errorDescription } = yield this._extractClientParams(req, authMethodsInstances, supported);
|
|
327
|
+
if (error) {
|
|
328
|
+
return h.response({ error: error, error_description: errorDescription || undefined }).code(400);
|
|
329
|
+
}
|
|
330
|
+
if (!clientId) {
|
|
331
|
+
return h
|
|
332
|
+
.response({
|
|
333
|
+
error: 'invalid_request',
|
|
334
|
+
error_description: `Supported token endpoint authentication methods: ${supported.join(', ')}`
|
|
335
|
+
}).code(400);
|
|
336
|
+
}
|
|
337
|
+
const hasRefreshToken = req.payload.refresh_token && typeof req.payload.refresh_token === 'string';
|
|
338
|
+
const isRefreshTokenGrantType = req.payload.grant_type === 'refresh_token';
|
|
339
|
+
if (clientId &&
|
|
340
|
+
hasRefreshToken &&
|
|
341
|
+
isRefreshTokenGrantType) {
|
|
342
|
+
const params = {
|
|
343
|
+
clientId,
|
|
344
|
+
grantType: `${req.payload.grant_type}`,
|
|
345
|
+
refreshToken: `${req.payload.refresh_token}`,
|
|
346
|
+
ttl: this.jwksGenerator.ttl,
|
|
347
|
+
createIDToken: hasOpenIDScope() ? ((payload) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
348
|
+
var _a;
|
|
349
|
+
return yield (0, jwks_generator_1.createIDToken)(this.jwksGenerator, Object.assign({ aud: clientId, iss: ((_a = t.postman) === null || _a === void 0 ? void 0 : _a.getHost()[0]) || '' }, payload));
|
|
350
|
+
})) : undefined
|
|
351
|
+
};
|
|
352
|
+
if (clientSecret) {
|
|
353
|
+
params.clientSecret = clientSecret;
|
|
354
|
+
}
|
|
355
|
+
if (req.payload.scope && typeof req.payload.scope === 'string') {
|
|
356
|
+
params.scope = req.payload.scope;
|
|
357
|
+
}
|
|
358
|
+
return (_a = this.refreshTokenRoute) === null || _a === void 0 ? void 0 : _a.handler(params, req, h);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
let error = 'unauthorized_client';
|
|
362
|
+
let errorDescription = '';
|
|
363
|
+
if (!clientId) {
|
|
364
|
+
error = 'invalid_request';
|
|
365
|
+
errorDescription = 'Request was missing the \'client_id\' parameter.';
|
|
366
|
+
}
|
|
367
|
+
else if (!(req.payload.refresh_token && typeof req.payload.refresh_token === 'string')) {
|
|
368
|
+
error = 'invalid_request';
|
|
369
|
+
errorDescription = 'Request was missing the \'refresh_token\' parameter.';
|
|
370
|
+
}
|
|
371
|
+
return h.response({ error, error_description: errorDescription }).code(400);
|
|
372
|
+
}
|
|
373
|
+
})
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
exports.OAuth2AuthorizationCode = OAuth2AuthorizationCode;
|
|
379
|
+
//#endregion OAuth2AuthorizationCode
|
|
380
|
+
//# sourceMappingURL=authentication-code.js.map
|