@rudderjs/passport 1.1.0 → 1.1.2
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.md +96 -15
- package/boost/guidelines.md +190 -0
- package/dist/grants/authorization-code.d.ts.map +1 -1
- package/dist/grants/authorization-code.js +4 -17
- package/dist/grants/authorization-code.js.map +1 -1
- package/dist/grants/client-credentials.d.ts.map +1 -1
- package/dist/grants/client-credentials.js +4 -17
- package/dist/grants/client-credentials.js.map +1 -1
- package/dist/grants/device-code.d.ts.map +1 -1
- package/dist/grants/device-code.js +2 -1
- package/dist/grants/device-code.js.map +1 -1
- package/dist/grants/parse-scopes.d.ts +15 -0
- package/dist/grants/parse-scopes.d.ts.map +1 -0
- package/dist/grants/parse-scopes.js +17 -0
- package/dist/grants/parse-scopes.js.map +1 -0
- package/dist/grants/refresh-token.d.ts.map +1 -1
- package/dist/grants/refresh-token.js +5 -18
- package/dist/grants/refresh-token.js.map +1 -1
- package/dist/grants/verify-client.d.ts +29 -0
- package/dist/grants/verify-client.d.ts.map +1 -0
- package/dist/grants/verify-client.js +43 -0
- package/dist/grants/verify-client.js.map +1 -0
- package/dist/middleware/bearer.d.ts.map +1 -1
- package/dist/middleware/bearer.js +98 -103
- package/dist/middleware/bearer.js.map +1 -1
- package/dist/models/AccessToken.d.ts +3 -3
- package/dist/models/AuthCode.d.ts +3 -3
- package/dist/models/DeviceCode.d.ts +3 -3
- package/dist/models/RefreshToken.d.ts +3 -3
- package/dist/models/helpers.d.ts +27 -9
- package/dist/models/helpers.d.ts.map +1 -1
- package/dist/models/helpers.js +12 -6
- package/dist/models/helpers.js.map +1 -1
- package/dist/personal-access-tokens.d.ts.map +1 -1
- package/dist/personal-access-tokens.js.map +1 -1
- package/dist/routes/authorize.d.ts +17 -0
- package/dist/routes/authorize.d.ts.map +1 -0
- package/dist/routes/authorize.js +107 -0
- package/dist/routes/authorize.js.map +1 -0
- package/dist/routes/device.d.ts +23 -0
- package/dist/routes/device.d.ts.map +1 -0
- package/dist/routes/device.js +69 -0
- package/dist/routes/device.js.map +1 -0
- package/dist/routes/helpers.d.ts +64 -0
- package/dist/routes/helpers.d.ts.map +1 -0
- package/dist/routes/helpers.js +154 -0
- package/dist/routes/helpers.js.map +1 -0
- package/dist/routes/revoke.d.ts +16 -0
- package/dist/routes/revoke.d.ts.map +1 -0
- package/dist/routes/revoke.js +33 -0
- package/dist/routes/revoke.js.map +1 -0
- package/dist/routes/scopes.d.ts +9 -0
- package/dist/routes/scopes.d.ts.map +1 -0
- package/dist/routes/scopes.js +13 -0
- package/dist/routes/scopes.js.map +1 -0
- package/dist/routes/token.d.ts +24 -0
- package/dist/routes/token.d.ts.map +1 -0
- package/dist/routes/token.js +121 -0
- package/dist/routes/token.js.map +1 -0
- package/dist/routes/types.d.ts +132 -0
- package/dist/routes/types.d.ts.map +1 -0
- package/dist/routes/types.js +2 -0
- package/dist/routes/types.js.map +1 -0
- package/dist/routes.d.ts +2 -120
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +16 -411
- package/dist/routes.js.map +1 -1
- package/package.json +7 -6
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Passport } from '../Passport.js';
|
|
2
2
|
import { accessTokenHelpers, refreshTokenHelpers } from '../models/helpers.js';
|
|
3
|
-
import { verifyClientSecret } from '../client-secret.js';
|
|
4
3
|
import { hashOpaqueToken } from '../opaque-token.js';
|
|
5
4
|
import { issueTokens } from './issue-tokens.js';
|
|
6
5
|
import { OAuthError } from './authorization-code.js';
|
|
6
|
+
import { parseScopes } from './parse-scopes.js';
|
|
7
|
+
import { verifyConfidentialCredentials } from './verify-client.js';
|
|
7
8
|
/**
|
|
8
9
|
* Refresh token grant — exchange a refresh token for a new access + refresh token pair.
|
|
9
10
|
* The old refresh token is revoked.
|
|
@@ -20,21 +21,7 @@ export async function refreshTokenGrant(params) {
|
|
|
20
21
|
if (!client || client.revoked) {
|
|
21
22
|
throw new OAuthError('invalid_client', 'Client not found.', 401);
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
-
if (client.confidential) {
|
|
25
|
-
if (!params.clientSecret) {
|
|
26
|
-
throw new OAuthError('invalid_client', 'Client secret required.', 401);
|
|
27
|
-
}
|
|
28
|
-
// Schema allows `client.secret` to be null; explicit guard so a future
|
|
29
|
-
// refactor can't mask `secret = null` as authenticating. See
|
|
30
|
-
// `client-credentials.ts` for the longer-form rationale.
|
|
31
|
-
if (client.secret == null) {
|
|
32
|
-
throw new OAuthError('invalid_client', 'Confidential client has no secret on file.', 401);
|
|
33
|
-
}
|
|
34
|
-
if (!(await verifyClientSecret(params.clientSecret, client.secret))) {
|
|
35
|
-
throw new OAuthError('invalid_client', 'Invalid client secret.', 401);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
24
|
+
await verifyConfidentialCredentials(client, params.clientSecret);
|
|
38
25
|
// Find refresh token by hashed plaintext (M5/P6) — the row's `id` is no
|
|
39
26
|
// longer the bearer secret, so a DB read leak doesn't yield usable tokens.
|
|
40
27
|
// Pre-migration tokens (which used `id` as the plaintext) won't match
|
|
@@ -70,8 +57,8 @@ export async function refreshTokenGrant(params) {
|
|
|
70
57
|
// Determine scopes — can only narrow, not widen
|
|
71
58
|
const originalScopes = accessTokenHelpers.getScopes(accessToken);
|
|
72
59
|
let scopes = originalScopes;
|
|
73
|
-
|
|
74
|
-
|
|
60
|
+
const requested = parseScopes(params.scope);
|
|
61
|
+
if (requested.length > 0) {
|
|
75
62
|
const invalid = requested.filter(s => !originalScopes.includes(s) && !originalScopes.includes('*'));
|
|
76
63
|
if (invalid.length > 0) {
|
|
77
64
|
throw new OAuthError('invalid_scope', `Cannot request scopes not in original token: ${invalid.join(', ')}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh-token.js","sourceRoot":"","sources":["../../src/grants/refresh-token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAIzC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"refresh-token.js","sourceRoot":"","sources":["../../src/grants/refresh-token.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { OAuthClient } from '../models/OAuthClient.js';
|
|
2
|
+
/**
|
|
3
|
+
* Verify client credentials at the token endpoint per RFC 6749 §2.3 / §5.2.
|
|
4
|
+
*
|
|
5
|
+
* Three failure modes return `invalid_client` 401 (with `WWW-Authenticate`
|
|
6
|
+
* set by the route handler on 401 responses):
|
|
7
|
+
*
|
|
8
|
+
* 1. **Missing secret** for a confidential client. The token endpoint
|
|
9
|
+
* requires a credential pair from confidential clients regardless of
|
|
10
|
+
* grant flow.
|
|
11
|
+
* 2. **`client.secret == null` on a confidential client.** The schema
|
|
12
|
+
* allows the column to be null (public clients legitimately have no
|
|
13
|
+
* secret). Hitting this branch on a confidential client is a data
|
|
14
|
+
* anomaly — explicit guard so a future refactor can't mask
|
|
15
|
+
* `secret = null` as authenticating against `verifyClientSecret(_, null)`
|
|
16
|
+
* (which fail-closes today, but the contract should be obvious).
|
|
17
|
+
* 3. **Hash mismatch.** Constant-time compare inside `verifyClientSecret`.
|
|
18
|
+
*
|
|
19
|
+
* `opts.requireConfidential` rejects non-confidential clients up front
|
|
20
|
+
* (`client_credentials` grant — RFC 6749 §4.4). Auth-code and refresh-token
|
|
21
|
+
* grants accept either kind; the credential pair is only checked when
|
|
22
|
+
* `client.confidential === true`. Public clients with no secret skip
|
|
23
|
+
* verification entirely and rely on PKCE / refresh-token-rotation for
|
|
24
|
+
* binding.
|
|
25
|
+
*/
|
|
26
|
+
export declare function verifyConfidentialCredentials(client: OAuthClient, clientSecret: string | undefined, opts?: {
|
|
27
|
+
requireConfidential?: boolean;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
//# sourceMappingURL=verify-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-client.d.ts","sourceRoot":"","sources":["../../src/grants/verify-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAI3D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,WAAW,EACnB,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,IAAI,GAAE;IAAE,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3C,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { verifyClientSecret } from '../client-secret.js';
|
|
2
|
+
import { OAuthError } from './authorization-code.js';
|
|
3
|
+
/**
|
|
4
|
+
* Verify client credentials at the token endpoint per RFC 6749 §2.3 / §5.2.
|
|
5
|
+
*
|
|
6
|
+
* Three failure modes return `invalid_client` 401 (with `WWW-Authenticate`
|
|
7
|
+
* set by the route handler on 401 responses):
|
|
8
|
+
*
|
|
9
|
+
* 1. **Missing secret** for a confidential client. The token endpoint
|
|
10
|
+
* requires a credential pair from confidential clients regardless of
|
|
11
|
+
* grant flow.
|
|
12
|
+
* 2. **`client.secret == null` on a confidential client.** The schema
|
|
13
|
+
* allows the column to be null (public clients legitimately have no
|
|
14
|
+
* secret). Hitting this branch on a confidential client is a data
|
|
15
|
+
* anomaly — explicit guard so a future refactor can't mask
|
|
16
|
+
* `secret = null` as authenticating against `verifyClientSecret(_, null)`
|
|
17
|
+
* (which fail-closes today, but the contract should be obvious).
|
|
18
|
+
* 3. **Hash mismatch.** Constant-time compare inside `verifyClientSecret`.
|
|
19
|
+
*
|
|
20
|
+
* `opts.requireConfidential` rejects non-confidential clients up front
|
|
21
|
+
* (`client_credentials` grant — RFC 6749 §4.4). Auth-code and refresh-token
|
|
22
|
+
* grants accept either kind; the credential pair is only checked when
|
|
23
|
+
* `client.confidential === true`. Public clients with no secret skip
|
|
24
|
+
* verification entirely and rely on PKCE / refresh-token-rotation for
|
|
25
|
+
* binding.
|
|
26
|
+
*/
|
|
27
|
+
export async function verifyConfidentialCredentials(client, clientSecret, opts = {}) {
|
|
28
|
+
if (opts.requireConfidential && !client.confidential) {
|
|
29
|
+
throw new OAuthError('invalid_client', 'Client credentials grant requires a confidential client.');
|
|
30
|
+
}
|
|
31
|
+
if (!client.confidential)
|
|
32
|
+
return;
|
|
33
|
+
if (!clientSecret) {
|
|
34
|
+
throw new OAuthError('invalid_client', 'Client secret required.', 401);
|
|
35
|
+
}
|
|
36
|
+
if (client.secret == null) {
|
|
37
|
+
throw new OAuthError('invalid_client', 'Confidential client has no secret on file.', 401);
|
|
38
|
+
}
|
|
39
|
+
if (!(await verifyClientSecret(clientSecret, client.secret))) {
|
|
40
|
+
throw new OAuthError('invalid_client', 'Invalid client secret.', 401);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=verify-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-client.js","sourceRoot":"","sources":["../../src/grants/verify-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,MAAmB,EACnB,YAAgC,EAChC,OAA0C,EAAE;IAE5C,IAAI,IAAI,CAAC,mBAAmB,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACrD,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,0DAA0D,CAAC,CAAA;IACpG,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,YAAY;QAAE,OAAM;IAEhC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,yBAAyB,EAAE,GAAG,CAAC,CAAA;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,4CAA4C,EAAE,GAAG,CAAC,CAAA;IAC3F,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,kBAAkB,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,wBAAwB,EAAE,GAAG,CAAC,CAAA;IACvE,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bearer.d.ts","sourceRoot":"","sources":["../../src/middleware/bearer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"bearer.d.ts","sourceRoot":"","sources":["../../src/middleware/bearer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAc,MAAM,qBAAqB,CAAA;AAsIxE;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,iBAAiB,CAKpD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,iBAAiB,CAkBjD"}
|
|
@@ -17,66 +17,99 @@ function extractBearer(authHeader) {
|
|
|
17
17
|
return authHeader.slice(7).trim() || null;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* Verify the JWT, look up the row by `jti`, and — on success — stamp
|
|
21
|
+
* `__passport_token` / `__passport_scopes` / `__passport_user_id` onto
|
|
22
|
+
* `req.raw`. If the JWT also carries a `sub`, resolve the user via the
|
|
23
|
+
* auth manager and copy a plain (function-stripped, password-stripped)
|
|
24
|
+
* snapshot onto `req.raw.__rjs_user` plus best-effort onto `req.user`.
|
|
25
|
+
*
|
|
26
|
+
* Returns the discriminated outcome so the two middleware exports can
|
|
27
|
+
* share the verification path without duplicating it. See `BearerMiddleware`
|
|
28
|
+
* and `RequireBearer` below for the failure-handling branches.
|
|
23
29
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
async function authenticateBearer(req) {
|
|
31
|
+
const authHeader = req.headers['authorization'];
|
|
32
|
+
const jwt = extractBearer(authHeader);
|
|
33
|
+
if (!jwt)
|
|
34
|
+
return { kind: 'no-bearer' };
|
|
35
|
+
let payload;
|
|
36
|
+
try {
|
|
37
|
+
// Pass expectedIssuer when configured so verifyToken rejects
|
|
38
|
+
// tokens minted by an unrelated issuer sharing the same keypair
|
|
39
|
+
// (multi-tenant / staging+prod). Tokens with no `iss` claim are
|
|
40
|
+
// legacy and exempt — see verifyToken jsdoc.
|
|
41
|
+
const issuer = Passport.issuer();
|
|
42
|
+
payload = await verifyToken(jwt, issuer ? { expectedIssuer: issuer } : undefined);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return { kind: 'invalid' };
|
|
46
|
+
}
|
|
47
|
+
// Revocation lookup — JWT signature is necessary but not sufficient.
|
|
48
|
+
const AccessTokenCls = await Passport.tokenModel();
|
|
49
|
+
const token = await AccessTokenCls.query()
|
|
50
|
+
.where('id', payload.jti)
|
|
51
|
+
.first();
|
|
52
|
+
if (!token || token.revoked)
|
|
53
|
+
return { kind: 'revoked' };
|
|
54
|
+
const raw = req.raw;
|
|
55
|
+
raw.__passport_token = token;
|
|
56
|
+
raw.__passport_scopes = payload.scopes;
|
|
57
|
+
raw.__passport_user_id = payload.sub;
|
|
58
|
+
if (payload.sub) {
|
|
59
|
+
await resolveAndStampUser(req, raw, payload.sub, token);
|
|
60
|
+
}
|
|
61
|
+
return { kind: 'authenticated' };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve the user via `auth.manager` and stamp `__passport_token` onto
|
|
65
|
+
* the resolved instance + a plain copy onto `raw.__rjs_user` and `req.user`.
|
|
66
|
+
*
|
|
67
|
+
* The plain copy strips functions + the `password` field so consumers reading
|
|
68
|
+
* `req.user` over an API can't accidentally leak the password hash. The
|
|
69
|
+
* `req.user` write is wrapped in try/catch because some adapters expose
|
|
70
|
+
* `req` as a frozen / read-only object (universal-middleware bridge); the
|
|
71
|
+
* raw-bag stamp is always reachable, the `req.user` write is best-effort.
|
|
72
|
+
*
|
|
73
|
+
* Failures inside this helper are swallowed — `@rudderjs/auth` is an
|
|
74
|
+
* optional peer, so a missing `auth.manager` binding is expected in apps
|
|
75
|
+
* that use bearer-only flows. The token bag on `req.raw` is already set
|
|
76
|
+
* by the caller; only the resolved-user convenience is missing.
|
|
77
|
+
*/
|
|
78
|
+
async function resolveAndStampUser(req, raw, userId, token) {
|
|
79
|
+
try {
|
|
80
|
+
const { app } = await import('@rudderjs/core');
|
|
81
|
+
const manager = app().make('auth.manager');
|
|
82
|
+
const user = await manager.guard().provider.retrieveById(userId);
|
|
83
|
+
if (!user)
|
|
30
84
|
return;
|
|
85
|
+
user['__passport_token'] = token;
|
|
86
|
+
const plain = {};
|
|
87
|
+
for (const [k, v] of Object.entries(user)) {
|
|
88
|
+
if (typeof v !== 'function' && k !== 'password')
|
|
89
|
+
plain[k] = v;
|
|
31
90
|
}
|
|
91
|
+
raw.__rjs_user = plain;
|
|
32
92
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// (multi-tenant / staging+prod). Tokens with no `iss` claim are
|
|
36
|
-
// legacy and exempt — see verifyToken jsdoc.
|
|
37
|
-
const issuer = Passport.issuer();
|
|
38
|
-
const payload = await verifyToken(jwt, issuer ? { expectedIssuer: issuer } : undefined);
|
|
39
|
-
// Check revocation in DB
|
|
40
|
-
const AccessTokenCls = await Passport.tokenModel();
|
|
41
|
-
const token = await AccessTokenCls.query()
|
|
42
|
-
.where('id', payload.jti)
|
|
43
|
-
.first();
|
|
44
|
-
if (!token || token.revoked) {
|
|
45
|
-
await next();
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
// Attach token info to the raw request
|
|
49
|
-
const raw = req.raw;
|
|
50
|
-
raw['__passport_token'] = token;
|
|
51
|
-
raw['__passport_scopes'] = payload.scopes;
|
|
52
|
-
raw['__passport_user_id'] = payload.sub;
|
|
53
|
-
// Resolve user if we have a userId
|
|
54
|
-
if (payload.sub) {
|
|
55
|
-
try {
|
|
56
|
-
const { app } = await import('@rudderjs/core');
|
|
57
|
-
const manager = app().make('auth.manager');
|
|
58
|
-
const user = await manager.guard().provider.retrieveById(payload.sub);
|
|
59
|
-
if (user) {
|
|
60
|
-
;
|
|
61
|
-
user['__passport_token'] = token;
|
|
62
|
-
const plain = {};
|
|
63
|
-
for (const [k, v] of Object.entries(user)) {
|
|
64
|
-
if (typeof v !== 'function' && k !== 'password')
|
|
65
|
-
plain[k] = v;
|
|
66
|
-
}
|
|
67
|
-
raw['__rjs_user'] = plain;
|
|
68
|
-
try {
|
|
69
|
-
req['user'] = plain;
|
|
70
|
-
}
|
|
71
|
-
catch { /* read-only */ }
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
catch { /* auth not available */ }
|
|
75
|
-
}
|
|
93
|
+
;
|
|
94
|
+
req['user'] = plain;
|
|
76
95
|
}
|
|
77
96
|
catch {
|
|
78
|
-
//
|
|
97
|
+
// Some adapters expose `req` as read-only — the raw-bag stamp above
|
|
98
|
+
// is the authoritative read path; this is the convenience copy.
|
|
79
99
|
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// auth.manager not bound — bearer-only flows are fine without it.
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Middleware that authenticates via Bearer token (JWT).
|
|
107
|
+
* Validates the JWT signature, checks expiration, checks revocation in DB.
|
|
108
|
+
* Attaches user to the request if valid. Does not block unauthenticated requests.
|
|
109
|
+
*/
|
|
110
|
+
export function BearerMiddleware() {
|
|
111
|
+
return async function BearerMiddleware(req, _res, next) {
|
|
112
|
+
await authenticateBearer(req);
|
|
80
113
|
await next();
|
|
81
114
|
};
|
|
82
115
|
}
|
|
@@ -85,58 +118,20 @@ export function BearerMiddleware() {
|
|
|
85
118
|
*/
|
|
86
119
|
export function RequireBearer() {
|
|
87
120
|
return async function RequireBearer(req, res, next) {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// (multi-tenant / staging+prod). Tokens with no `iss` claim are
|
|
98
|
-
// legacy and exempt — see verifyToken jsdoc.
|
|
99
|
-
const issuer = Passport.issuer();
|
|
100
|
-
const payload = await verifyToken(jwt, issuer ? { expectedIssuer: issuer } : undefined);
|
|
101
|
-
// Check revocation
|
|
102
|
-
const AccessTokenCls = await Passport.tokenModel();
|
|
103
|
-
const token = await AccessTokenCls.query()
|
|
104
|
-
.where('id', payload.jti)
|
|
105
|
-
.first();
|
|
106
|
-
if (!token || token.revoked) {
|
|
121
|
+
const outcome = await authenticateBearer(req);
|
|
122
|
+
switch (outcome.kind) {
|
|
123
|
+
case 'authenticated':
|
|
124
|
+
await next();
|
|
125
|
+
return;
|
|
126
|
+
case 'no-bearer':
|
|
127
|
+
res.status(401).json({ error: 'unauthenticated', message: 'Bearer token required.' });
|
|
128
|
+
return;
|
|
129
|
+
case 'revoked':
|
|
107
130
|
res.status(401).json({ error: 'unauthenticated', message: 'Token has been revoked.' });
|
|
108
131
|
return;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
raw['__passport_scopes'] = payload.scopes;
|
|
113
|
-
raw['__passport_user_id'] = payload.sub;
|
|
114
|
-
if (payload.sub) {
|
|
115
|
-
try {
|
|
116
|
-
const { app } = await import('@rudderjs/core');
|
|
117
|
-
const manager = app().make('auth.manager');
|
|
118
|
-
const user = await manager.guard().provider.retrieveById(payload.sub);
|
|
119
|
-
if (user) {
|
|
120
|
-
;
|
|
121
|
-
user['__passport_token'] = token;
|
|
122
|
-
const plain = {};
|
|
123
|
-
for (const [k, v] of Object.entries(user)) {
|
|
124
|
-
if (typeof v !== 'function' && k !== 'password')
|
|
125
|
-
plain[k] = v;
|
|
126
|
-
}
|
|
127
|
-
raw['__rjs_user'] = plain;
|
|
128
|
-
try {
|
|
129
|
-
req['user'] = plain;
|
|
130
|
-
}
|
|
131
|
-
catch { /* read-only */ }
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
catch { /* auth not available */ }
|
|
135
|
-
}
|
|
136
|
-
await next();
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
res.status(401).json({ error: 'unauthenticated', message: 'Invalid or expired token.' });
|
|
132
|
+
case 'invalid':
|
|
133
|
+
res.status(401).json({ error: 'unauthenticated', message: 'Invalid or expired token.' });
|
|
134
|
+
return;
|
|
140
135
|
}
|
|
141
136
|
};
|
|
142
137
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bearer.js","sourceRoot":"","sources":["../../src/middleware/bearer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGzC;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,UAA8B;IACnD,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAA;IAC5B,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACtC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACnE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAA;AAC3C,CAAC;
|
|
1
|
+
{"version":3,"file":"bearer.js","sourceRoot":"","sources":["../../src/middleware/bearer.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,9 +29,9 @@ export declare class AccessToken extends Model {
|
|
|
29
29
|
/** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
|
|
30
30
|
static pruneMode: "mass";
|
|
31
31
|
/** Rows safe to remove: expired OR revoked. Same predicate as `passport:purge`. */
|
|
32
|
-
static prunable(): import("@rudderjs/
|
|
33
|
-
scope(name: string, ...args: unknown[]): import("@rudderjs/
|
|
34
|
-
withoutGlobalScope(name: string): import("@rudderjs/
|
|
32
|
+
static prunable(): import("@rudderjs/orm").HydratingQueryBuilder<AccessToken> & {
|
|
33
|
+
scope(name: string, ...args: unknown[]): import("@rudderjs/orm").HydratingQueryBuilder<AccessToken>;
|
|
34
|
+
withoutGlobalScope(name: string): import("@rudderjs/orm").HydratingQueryBuilder<AccessToken>;
|
|
35
35
|
};
|
|
36
36
|
id: string;
|
|
37
37
|
userId: string | null;
|
|
@@ -10,9 +10,9 @@ export declare class AuthCode extends Model {
|
|
|
10
10
|
* replay-detection diagnostics; we wait for the natural 10-minute TTL
|
|
11
11
|
* before reaping. Mirrors the `passport:purge` predicate.
|
|
12
12
|
*/
|
|
13
|
-
static prunable(): import("@rudderjs/
|
|
14
|
-
scope(name: string, ...args: unknown[]): import("@rudderjs/
|
|
15
|
-
withoutGlobalScope(name: string): import("@rudderjs/
|
|
13
|
+
static prunable(): import("@rudderjs/orm").HydratingQueryBuilder<AuthCode> & {
|
|
14
|
+
scope(name: string, ...args: unknown[]): import("@rudderjs/orm").HydratingQueryBuilder<AuthCode>;
|
|
15
|
+
withoutGlobalScope(name: string): import("@rudderjs/orm").HydratingQueryBuilder<AuthCode>;
|
|
16
16
|
};
|
|
17
17
|
id: string;
|
|
18
18
|
/** SHA-256 hex of the plaintext authorization code. See `opaque-token.ts`. */
|
|
@@ -5,9 +5,9 @@ export declare class DeviceCode extends Model {
|
|
|
5
5
|
/** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
|
|
6
6
|
static pruneMode: "mass";
|
|
7
7
|
/** Rows safe to remove: expired only. Mirrors the `passport:purge` predicate. */
|
|
8
|
-
static prunable(): import("@rudderjs/
|
|
9
|
-
scope(name: string, ...args: unknown[]): import("@rudderjs/
|
|
10
|
-
withoutGlobalScope(name: string): import("@rudderjs/
|
|
8
|
+
static prunable(): import("@rudderjs/orm").HydratingQueryBuilder<DeviceCode> & {
|
|
9
|
+
scope(name: string, ...args: unknown[]): import("@rudderjs/orm").HydratingQueryBuilder<DeviceCode>;
|
|
10
|
+
withoutGlobalScope(name: string): import("@rudderjs/orm").HydratingQueryBuilder<DeviceCode>;
|
|
11
11
|
};
|
|
12
12
|
id: string;
|
|
13
13
|
clientId: string;
|
|
@@ -5,9 +5,9 @@ export declare class RefreshToken extends Model {
|
|
|
5
5
|
/** `MassPrunable` — bulk `deleteAll()` per chunk; mirrors `passport:purge`. */
|
|
6
6
|
static pruneMode: "mass";
|
|
7
7
|
/** Rows safe to remove: expired OR revoked. Same predicate as `passport:purge`. */
|
|
8
|
-
static prunable(): import("@rudderjs/
|
|
9
|
-
scope(name: string, ...args: unknown[]): import("@rudderjs/
|
|
10
|
-
withoutGlobalScope(name: string): import("@rudderjs/
|
|
8
|
+
static prunable(): import("@rudderjs/orm").HydratingQueryBuilder<RefreshToken> & {
|
|
9
|
+
scope(name: string, ...args: unknown[]): import("@rudderjs/orm").HydratingQueryBuilder<RefreshToken>;
|
|
10
|
+
withoutGlobalScope(name: string): import("@rudderjs/orm").HydratingQueryBuilder<RefreshToken>;
|
|
11
11
|
};
|
|
12
12
|
id: string;
|
|
13
13
|
accessTokenId: string;
|
package/dist/models/helpers.d.ts
CHANGED
|
@@ -2,9 +2,12 @@ export interface OAuthClientRecord {
|
|
|
2
2
|
id: string;
|
|
3
3
|
name: string;
|
|
4
4
|
secret: string | null;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
/** JSON-encoded array on the wire; `string[]` after `@Cast('json')` hydration. */
|
|
6
|
+
redirectUris: unknown;
|
|
7
|
+
/** JSON-encoded array on the wire; `string[]` after `@Cast('json')` hydration. */
|
|
8
|
+
grantTypes: unknown;
|
|
9
|
+
/** JSON-encoded array on the wire; `string[]` after `@Cast('json')` hydration. */
|
|
10
|
+
scopes: unknown;
|
|
8
11
|
confidential: boolean;
|
|
9
12
|
revoked: boolean;
|
|
10
13
|
}
|
|
@@ -13,10 +16,17 @@ export interface AccessTokenRecord {
|
|
|
13
16
|
userId: string | null;
|
|
14
17
|
clientId: string;
|
|
15
18
|
name: string | null;
|
|
16
|
-
|
|
19
|
+
/**
|
|
20
|
+
* JSON-encoded array on the wire; `string[]` if a future `@Cast('json')`
|
|
21
|
+
* hydrates it. Optional in the type because `AccessToken` doesn't `declare`
|
|
22
|
+
* it (the Model carries it as an untyped DB-only column today); the runtime
|
|
23
|
+
* parser fail-closes to `[]` if missing.
|
|
24
|
+
*/
|
|
25
|
+
scopes?: unknown;
|
|
17
26
|
revoked: boolean;
|
|
18
27
|
expiresAt: Date;
|
|
19
|
-
|
|
28
|
+
/** Populated by the ORM; not declared on the Model. */
|
|
29
|
+
createdAt?: Date;
|
|
20
30
|
}
|
|
21
31
|
export interface RefreshTokenRecord {
|
|
22
32
|
id: string;
|
|
@@ -33,7 +43,12 @@ export interface AuthCodeRecord {
|
|
|
33
43
|
tokenHash: string;
|
|
34
44
|
userId: string;
|
|
35
45
|
clientId: string;
|
|
36
|
-
|
|
46
|
+
/**
|
|
47
|
+
* JSON-encoded array on the wire; `string[]` if a future `@Cast('json')`
|
|
48
|
+
* hydrates it. Optional because `AuthCode` doesn't `declare` it; the
|
|
49
|
+
* runtime parser fail-closes to `[]` if missing.
|
|
50
|
+
*/
|
|
51
|
+
scopes?: unknown;
|
|
37
52
|
revoked: boolean;
|
|
38
53
|
expiresAt: Date;
|
|
39
54
|
redirectUri: string | null;
|
|
@@ -43,9 +58,12 @@ export interface AuthCodeRecord {
|
|
|
43
58
|
export interface DeviceCodeRecord {
|
|
44
59
|
id: string;
|
|
45
60
|
clientId: string;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
61
|
+
/**
|
|
62
|
+
* JSON-encoded array on the wire; `string[]` if a future `@Cast('json')`
|
|
63
|
+
* hydrates it. Optional because `DeviceCode` doesn't `declare` it; the
|
|
64
|
+
* runtime parser fail-closes to `[]` if missing.
|
|
65
|
+
*/
|
|
66
|
+
scopes?: unknown;
|
|
49
67
|
userId: string | null;
|
|
50
68
|
approved: boolean | null;
|
|
51
69
|
expiresAt: Date;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/models/helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/models/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/models/helpers.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
// Helper functions that operate on
|
|
1
|
+
// Helper functions that operate on OAuth records — both Model instances
|
|
2
2
|
// (returned from the ORM read paths since PR #111 on 2026-04-30) and raw rows
|
|
3
|
-
// (cached JSON, fixtures, adapter-level snapshots).
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// the
|
|
3
|
+
// (cached JSON, fixtures, adapter-level snapshots). JSON-encoded columns are
|
|
4
|
+
// typed as `unknown` here because the runtime parser (`parseJsonArray`)
|
|
5
|
+
// already accepts both the wire shape (`string` JSON) and the hydrated shape
|
|
6
|
+
// (`string[]` from `@Cast('json')` on the Models). Same helper, same return
|
|
7
|
+
// type, no `as any` at the call site needed to bridge between the two.
|
|
8
|
+
//
|
|
9
|
+
// The Model classes also expose equivalent instance methods
|
|
10
|
+
// (`OAuthClient.hasGrantType()`, `AccessToken.can()`, `DeviceCode.isExpired()`)
|
|
11
|
+
// — those are the more direct API once you already hold a Model instance.
|
|
12
|
+
// These helpers stay for callers that genuinely have raw records (cached
|
|
13
|
+
// JSON, fixtures, the corrupt-JSON fail-closed test path).
|
|
8
14
|
// ─── Parsing helpers ──────────────────────────────────────
|
|
9
15
|
function parseJsonArray(raw) {
|
|
10
16
|
if (Array.isArray(raw))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/models/helpers.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/models/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"personal-access-tokens.d.ts","sourceRoot":"","sources":["../src/personal-access-tokens.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAO1D,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,KAAK,EAAE,WAAW,CAAA;IAClB,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAA;CACvB;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACnG,MAAM,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IAChC,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC;
|
|
1
|
+
{"version":3,"file":"personal-access-tokens.d.ts","sourceRoot":"","sources":["../src/personal-access-tokens.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAO1D,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,KAAK,EAAE,WAAW,CAAA;IAClB,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAA;CACvB;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACnG,MAAM,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAA;IAChC,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC;AAiBD,wBAAgB,YAAY,CAAC,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACzE,IAAI,EAAE,CAAC,GACN,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,oBAAoB,CAAC,CAwGpD;AAoCD,wDAAwD;AACxD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"personal-access-tokens.js","sourceRoot":"","sources":["../src/personal-access-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAGxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"personal-access-tokens.js","sourceRoot":"","sources":["../src/personal-access-tokens.ts"],"names":[],"mappings":"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"}
|