@fluojs/passport 1.0.0 → 1.0.1
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/README.ko.md +3 -3
- package/README.md +3 -3
- package/dist/account/account-linking.d.ts.map +1 -1
- package/dist/account/account-linking.js +10 -3
- package/dist/adapters/passport-js.d.ts +2 -0
- package/dist/adapters/passport-js.d.ts.map +1 -1
- package/dist/adapters/passport-js.js +22 -0
- package/dist/cookie/cookie-auth.js +1 -1
- package/dist/refresh/refresh-token.js +2 -3
- package/package.json +4 -4
package/README.ko.md
CHANGED
|
@@ -106,7 +106,7 @@ const googleBridge = createPassportJsStrategyBridge('google', GoogleStrategy, {
|
|
|
106
106
|
});
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
브릿지는 각 Passport.js 전략 실행을 정확히 한 번만 정착(settle)시킵니다. 전략은 바인딩된 Passport 액션(`success`, `fail`, `redirect`, `pass`, `error`) 중 하나를 호출해야 하며, promise rejection
|
|
109
|
+
브릿지는 각 Passport.js 전략 실행을 정확히 한 번만 정착(settle)시킵니다. 전략은 바인딩된 Passport 액션(`success`, `fail`, `redirect`, `pass`, `error`) 중 하나를 호출해야 하며, promise rejection, 액션 없이 완료된 promise, 그리고 제한된 action timeout을 초과한 callback-style 실행은 요청을 미해결 상태로 두지 않고 인증 실패로 처리됩니다. 커스텀 `mapPrincipal` 함수는 비어 있지 않은 `subject`와 객체 형태의 `claims`를 포함한 유효한 fluo `Principal`을 반환해야 합니다.
|
|
110
110
|
|
|
111
111
|
### 쿠키 인증 프리셋
|
|
112
112
|
|
|
@@ -201,11 +201,11 @@ export class AuthController {
|
|
|
201
201
|
|
|
202
202
|
`RefreshTokenModule.forRoot(...)`를 `PassportModule.forRoot(...)`와 함께 import 하여 refresh-token 전략과 공유 `REFRESH_TOKEN_SERVICE` alias를 같은 모듈 wiring에서 사용하세요.
|
|
203
203
|
|
|
204
|
-
`RefreshTokenStrategy`는 `body.refreshToken`, `Authorization: Bearer ...`, `x-refresh-token`에서 token을 읽습니다. Malformed non-string token은 인증 실패로 처리됩니다. `JwtRefreshTokenAdapter`는 `secret`과 backing store가 필요하며, `store: 'memory'`는 development 및 single-instance deployment
|
|
204
|
+
`RefreshTokenStrategy`는 `body.refreshToken`, `Authorization: Bearer ...`, `x-refresh-token`에서 token을 읽습니다. Malformed non-string token은 인증 실패로 처리됩니다. Rotation 후에는 `@fluojs/jwt`가 반환한 정규화 access-token principal subject를 신뢰합니다. `JwtRefreshTokenAdapter`는 `secret`과 backing store가 필요하며, `store: 'memory'`는 development 및 single-instance deployment용이고 rotation은 store consume contract를 통해 재사용을 감지합니다.
|
|
205
205
|
|
|
206
206
|
### Account linking과 status
|
|
207
207
|
|
|
208
|
-
Identity-link 결정을 모델링하려면 `createConservativeAccountLinkPolicy(...)`와 `resolveAccountLinking(...)`을 사용합니다. 기본 conservative policy는
|
|
208
|
+
Identity-link 결정을 모델링하려면 `createConservativeAccountLinkPolicy(...)`와 `resolveAccountLinking(...)`을 사용합니다. 기본 conservative policy는 모호하지 않은 단일 existing account link 또는 user-confirmed match만 연결하고, 여러 existing link는 conflict로 보고하며, 그 외에는 create/skip/reject/conflict를 결정적으로 처리합니다.
|
|
209
209
|
|
|
210
210
|
`createPassportPlatformStatusSnapshot(...)`와 `createPassportPlatformDiagnosticIssues(...)`는 등록된 strategy, default strategy 설정, preset, refresh-token store readiness에 대한 readiness/health diagnostic을 노출합니다.
|
|
211
211
|
|
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ const googleBridge = createPassportJsStrategyBridge('google', GoogleStrategy, {
|
|
|
106
106
|
});
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
The bridge settles each Passport.js strategy execution exactly once. A strategy must call one of the bound Passport actions (`success`, `fail`, `redirect`, `pass`, or `error`); promise rejections
|
|
109
|
+
The bridge settles each Passport.js strategy execution exactly once. A strategy must call one of the bound Passport actions (`success`, `fail`, `redirect`, `pass`, or `error`); promise rejections, promise completion without an action, and callback-style executions that exceed the bounded action timeout become authentication failures instead of leaving the request unresolved. Custom `mapPrincipal` functions must return a valid fluo `Principal` with a non-empty `subject` and object `claims`.
|
|
110
110
|
|
|
111
111
|
### Cookie Auth Preset
|
|
112
112
|
|
|
@@ -201,11 +201,11 @@ export class AuthController {
|
|
|
201
201
|
|
|
202
202
|
Import `RefreshTokenModule.forRoot(...)` alongside `PassportModule.forRoot(...)` so the refresh-token strategy and shared `REFRESH_TOKEN_SERVICE` alias are available in the same module wiring.
|
|
203
203
|
|
|
204
|
-
`RefreshTokenStrategy` reads tokens from `body.refreshToken`, `Authorization: Bearer ...`, or `x-refresh-token`; malformed non-string tokens fail authentication. `JwtRefreshTokenAdapter` requires a `secret` and a backing store; `store: 'memory'` is for development and single-instance deployments only.
|
|
204
|
+
`RefreshTokenStrategy` reads tokens from `body.refreshToken`, `Authorization: Bearer ...`, or `x-refresh-token`; malformed non-string tokens fail authentication. After rotation, it trusts the normalized access-token principal subject returned by `@fluojs/jwt`. `JwtRefreshTokenAdapter` requires a `secret` and a backing store; `store: 'memory'` is for development and single-instance deployments only, and rotation detects reuse through the store consume contract.
|
|
205
205
|
|
|
206
206
|
### Account Linking and Status
|
|
207
207
|
|
|
208
|
-
Use `createConservativeAccountLinkPolicy(...)` and `resolveAccountLinking(...)` to model identity-link decisions. The default conservative policy links
|
|
208
|
+
Use `createConservativeAccountLinkPolicy(...)` and `resolveAccountLinking(...)` to model identity-link decisions. The default conservative policy links one unambiguous existing account link or user-confirmed matches, reports multiple existing links as conflicts, and otherwise creates, skips, rejects, or reports conflicts deterministically.
|
|
209
209
|
|
|
210
210
|
`createPassportPlatformStatusSnapshot(...)` and `createPassportPlatformDiagnosticIssues(...)` expose readiness/health diagnostics for registered strategies, default strategy configuration, presets, and refresh-token store readiness.
|
|
211
211
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-linking.d.ts","sourceRoot":"","sources":["../../src/account/account-linking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5D,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,eAAqD,CAAC;AAEzF,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,oEAAoE;AACpE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,eAAe,GAAG,aAAa,GAAG,gBAAgB,GAAG,MAAM,CAAC;CACrE;AAED,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,uEAAuE;AACvE,MAAM,MAAM,yBAAyB,GACjC;IACE,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEN,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;CAChF;AAED,8DAA8D;AAC9D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;CACtC;AAED,iEAAiE;AACjE,MAAM,MAAM,wBAAwB,GAChC;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,6EAA6E;AAC7E,qBAAa,wBAAyB,SAAQ,SAAS;IACrD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC;gBAGrC,mBAAmB,EAAE,MAAM,EAAE,EAC7B,OAAO,SAAoE;CAW9E;AAED,0EAA0E;AAC1E,qBAAa,wBAAyB,SAAQ,SAAS;gBACzC,OAAO,SAA0C,EAAE,IAAI,SAA0B;CAG9F;AAED;;;;GAIG;AACH,wBAAgB,mCAAmC,IAAI,iBAAiB,
|
|
1
|
+
{"version":3,"file":"account-linking.d.ts","sourceRoot":"","sources":["../../src/account/account-linking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5D,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,eAAqD,CAAC;AAEzF,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,oEAAoE;AACpE,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,eAAe,GAAG,aAAa,GAAG,gBAAgB,GAAG,MAAM,CAAC;CACrE;AAED,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,uEAAuE;AACvE,MAAM,MAAM,yBAAyB,GACjC;IACE,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEN,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;CAChF;AAED,8DAA8D;AAC9D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;CACtC;AAED,iEAAiE;AACjE,MAAM,MAAM,wBAAwB,GAChC;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,6EAA6E;AAC7E,qBAAa,wBAAyB,SAAQ,SAAS;IACrD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC;gBAGrC,mBAAmB,EAAE,MAAM,EAAE,EAC7B,OAAO,SAAoE;CAW9E;AAED,0EAA0E;AAC1E,qBAAa,wBAAyB,SAAQ,SAAS;gBACzC,OAAO,SAA0C,EAAE,IAAI,SAA0B;CAG9F;AAED;;;;GAIG;AACH,wBAAgB,mCAAmC,IAAI,iBAAiB,CAqEvE;AAKD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,CAAC,EAAE,iBAAiB,EAC1B,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,wBAAwB,CAAC,CA0CnC"}
|
|
@@ -50,14 +50,21 @@ export class AccountLinkRejectedError extends FluoError {
|
|
|
50
50
|
export function createConservativeAccountLinkPolicy() {
|
|
51
51
|
return {
|
|
52
52
|
evaluate(context) {
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
53
|
+
const existingLinkAccountIds = Array.from(new Set(context.candidates.filter(candidate => candidate.reason === 'existing-link').map(candidate => candidate.accountId)));
|
|
54
|
+
if (existingLinkAccountIds.length === 1) {
|
|
55
55
|
return {
|
|
56
56
|
action: 'link',
|
|
57
|
-
accountId:
|
|
57
|
+
accountId: existingLinkAccountIds[0],
|
|
58
58
|
reason: 'Existing identity link found.'
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
+
if (existingLinkAccountIds.length > 1) {
|
|
62
|
+
return {
|
|
63
|
+
action: 'conflict',
|
|
64
|
+
candidateAccountIds: existingLinkAccountIds,
|
|
65
|
+
reason: 'Multiple existing identity links matched. Explicit review is required before linking.'
|
|
66
|
+
};
|
|
67
|
+
}
|
|
61
68
|
const linkAttempt = context.linkAttempt;
|
|
62
69
|
if (linkAttempt) {
|
|
63
70
|
if (!linkAttempt.confirmedByUser) {
|
|
@@ -38,6 +38,8 @@ export type PassportJsPrincipalMapper = (input: PassportJsPrincipalMapperInput)
|
|
|
38
38
|
export interface PassportJsAuthStrategyOptions {
|
|
39
39
|
/** Optional options to pass to the Passport strategy's `authenticate` method. */
|
|
40
40
|
authenticateOptions?: Readonly<Record<string, unknown>>;
|
|
41
|
+
/** Maximum time to wait for callback-style strategies to call a bound Passport action. */
|
|
42
|
+
actionTimeoutMs?: number;
|
|
41
43
|
/** Optional custom mapper for converting user data to a principal. */
|
|
42
44
|
mapPrincipal?: PassportJsPrincipalMapper;
|
|
43
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passport-js.d.ts","sourceRoot":"","sources":["../../src/adapters/passport-js.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAU7F;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC5D;
|
|
1
|
+
{"version":3,"file":"passport-js.d.ts","sourceRoot":"","sources":["../../src/adapters/passport-js.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAU7F;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC5D;AAcD;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C,iDAAiD;IACjD,OAAO,EAAE,YAAY,CAAC;IACtB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yDAAyD;IACzD,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,8BAA8B,KAAK,SAAS,CAAC;AAE7F;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,0FAA0F;IAC1F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,YAAY,CAAC,EAAE,yBAAyB,CAAC;CAC1C;AAID;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,EAAE,wBAAwB,CAAC;CACpC;AAoGD;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,YAAY;IAIvD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuE;gBAGjF,gBAAgB,EAAE,sBAAsB,EACxC,OAAO,GAAE,6BAAkC;IAG9D,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,GAAG,iBAAiB,CAAC;IAgE3E,OAAO,CAAC,wBAAwB;IAmBhC,OAAO,CAAC,MAAM;IAiBd,OAAO,CAAC,mBAAmB;IAqC3B,OAAO,CAAC,kBAAkB;CAS3B;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,KAAK,CAAC,sBAAsB,CAAC,EAC5C,OAAO,GAAE,6BAAkC,GAC1C,wBAAwB,CAwB1B"}
|
|
@@ -19,6 +19,8 @@ import { normalizePrincipalScopes } from '../scope.js';
|
|
|
19
19
|
* Configuration options for the Passport.js authentication strategy.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
const DEFAULT_ACTION_TIMEOUT_MS = 30_000;
|
|
23
|
+
|
|
22
24
|
/**
|
|
23
25
|
* Bridge interface containing DI providers and strategy registration for Passport.js.
|
|
24
26
|
*/
|
|
@@ -112,7 +114,15 @@ export class PassportJsAuthStrategy {
|
|
|
112
114
|
const strategy = this.createExecutableStrategy();
|
|
113
115
|
const mapPrincipal = this.options.mapPrincipal ?? defaultPrincipalMapper;
|
|
114
116
|
return new Promise((resolve, reject) => {
|
|
117
|
+
let actionTimeout;
|
|
118
|
+
const clearActionTimeout = () => {
|
|
119
|
+
if (actionTimeout) {
|
|
120
|
+
clearTimeout(actionTimeout);
|
|
121
|
+
actionTimeout = undefined;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
115
124
|
this.requestState.set(strategy, {
|
|
125
|
+
clearActionTimeout,
|
|
116
126
|
context,
|
|
117
127
|
mapPrincipal,
|
|
118
128
|
reject,
|
|
@@ -121,20 +131,31 @@ export class PassportJsAuthStrategy {
|
|
|
121
131
|
settled: false
|
|
122
132
|
});
|
|
123
133
|
this.bindStrategyActions(strategy);
|
|
134
|
+
const actionTimeoutMs = this.options.actionTimeoutMs ?? DEFAULT_ACTION_TIMEOUT_MS;
|
|
135
|
+
if (Number.isFinite(actionTimeoutMs) && actionTimeoutMs >= 0) {
|
|
136
|
+
actionTimeout = setTimeout(() => {
|
|
137
|
+
this.settle(strategy, state => {
|
|
138
|
+
state.reject(new AuthenticationRequiredError('Passport strategy did not settle authentication.'));
|
|
139
|
+
});
|
|
140
|
+
}, actionTimeoutMs);
|
|
141
|
+
}
|
|
124
142
|
try {
|
|
125
143
|
const result = strategy.authenticate(request, this.options.authenticateOptions);
|
|
126
144
|
if (isPromiseLike(result)) {
|
|
127
145
|
result.then(() => {
|
|
146
|
+
clearActionTimeout();
|
|
128
147
|
this.settle(strategy, state => {
|
|
129
148
|
state.reject(new AuthenticationRequiredError('Passport strategy did not settle authentication.'));
|
|
130
149
|
});
|
|
131
150
|
}, error => {
|
|
151
|
+
clearActionTimeout();
|
|
132
152
|
this.settle(strategy, state => {
|
|
133
153
|
state.reject(error);
|
|
134
154
|
});
|
|
135
155
|
});
|
|
136
156
|
}
|
|
137
157
|
} catch (error) {
|
|
158
|
+
clearActionTimeout();
|
|
138
159
|
this.settle(strategy, () => reject(error));
|
|
139
160
|
}
|
|
140
161
|
});
|
|
@@ -161,6 +182,7 @@ export class PassportJsAuthStrategy {
|
|
|
161
182
|
try {
|
|
162
183
|
handler(state);
|
|
163
184
|
} finally {
|
|
185
|
+
state.clearActionTimeout?.();
|
|
164
186
|
this.requestState.delete(strategy);
|
|
165
187
|
}
|
|
166
188
|
}
|
|
@@ -74,7 +74,7 @@ class CookieAuthStrategy {
|
|
|
74
74
|
return unauthenticatedCookieAuthResult;
|
|
75
75
|
}
|
|
76
76
|
const accessToken = cookies[this.options.accessTokenCookieName];
|
|
77
|
-
if (accessToken === undefined
|
|
77
|
+
if (accessToken === undefined) {
|
|
78
78
|
if (this.options.requireAccessToken) {
|
|
79
79
|
throw new AuthenticationRequiredError('Access token cookie is required.');
|
|
80
80
|
}
|
|
@@ -105,11 +105,10 @@ class RefreshTokenStrategy {
|
|
|
105
105
|
}
|
|
106
106
|
async extractVerifiedSubject(accessToken) {
|
|
107
107
|
const principal = await this.verifier.verifyAccessToken(accessToken);
|
|
108
|
-
|
|
109
|
-
if (typeof sub !== 'string' || sub.length === 0) {
|
|
108
|
+
if (typeof principal.subject !== 'string' || principal.subject.length === 0) {
|
|
110
109
|
throw new InvariantError('Refresh token service returned an access token without a valid subject claim.');
|
|
111
110
|
}
|
|
112
|
-
return
|
|
111
|
+
return principal.subject;
|
|
113
112
|
}
|
|
114
113
|
static {
|
|
115
114
|
_initClass();
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"guard",
|
|
10
10
|
"strategy"
|
|
11
11
|
],
|
|
12
|
-
"version": "1.0.
|
|
12
|
+
"version": "1.0.1",
|
|
13
13
|
"private": false,
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"repository": {
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"dist"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@fluojs/core": "^1.0.
|
|
40
|
-
"@fluojs/di": "^1.0.
|
|
39
|
+
"@fluojs/core": "^1.0.1",
|
|
40
|
+
"@fluojs/di": "^1.0.1",
|
|
41
41
|
"@fluojs/http": "^1.0.0",
|
|
42
42
|
"@fluojs/jwt": "^1.0.0",
|
|
43
|
-
"@fluojs/runtime": "^1.0.
|
|
43
|
+
"@fluojs/runtime": "^1.0.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"vitest": "^3.2.4"
|