@rudderjs/passport 0.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/LICENSE +21 -0
- package/dist/Passport.d.ts +41 -0
- package/dist/Passport.d.ts.map +1 -0
- package/dist/Passport.js +77 -0
- package/dist/Passport.js.map +1 -0
- package/dist/commands/client.d.ts +16 -0
- package/dist/commands/client.d.ts.map +1 -0
- package/dist/commands/client.js +25 -0
- package/dist/commands/client.js.map +1 -0
- package/dist/commands/keys.d.ts +11 -0
- package/dist/commands/keys.d.ts.map +1 -0
- package/dist/commands/keys.js +27 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/purge.d.ts +11 -0
- package/dist/commands/purge.d.ts.map +1 -0
- package/dist/commands/purge.js +48 -0
- package/dist/commands/purge.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/bearer.d.ts +12 -0
- package/dist/middleware/bearer.d.ts.map +1 -0
- package/dist/middleware/bearer.js +111 -0
- package/dist/middleware/bearer.js.map +1 -0
- package/dist/middleware/scope.d.ts +11 -0
- package/dist/middleware/scope.d.ts.map +1 -0
- package/dist/middleware/scope.js +39 -0
- package/dist/middleware/scope.js.map +1 -0
- package/dist/models/AccessToken.d.ts +23 -0
- package/dist/models/AccessToken.d.ts.map +1 -0
- package/dist/models/AccessToken.js +35 -0
- package/dist/models/AccessToken.js.map +1 -0
- package/dist/models/AuthCode.d.ts +18 -0
- package/dist/models/AuthCode.d.ts.map +1 -0
- package/dist/models/AuthCode.js +21 -0
- package/dist/models/AuthCode.js.map +1 -0
- package/dist/models/DeviceCode.d.ts +23 -0
- package/dist/models/DeviceCode.d.ts.map +1 -0
- package/dist/models/DeviceCode.js +29 -0
- package/dist/models/DeviceCode.js.map +1 -0
- package/dist/models/OAuthClient.d.ts +22 -0
- package/dist/models/OAuthClient.d.ts.map +1 -0
- package/dist/models/OAuthClient.js +52 -0
- package/dist/models/OAuthClient.js.map +1 -0
- package/dist/models/RefreshToken.d.ts +13 -0
- package/dist/models/RefreshToken.d.ts.map +1 -0
- package/dist/models/RefreshToken.js +15 -0
- package/dist/models/RefreshToken.js.map +1 -0
- package/dist/token.d.ts +40 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +80 -0
- package/dist/token.js.map +1 -0
- package/package.json +51 -0
- package/schema/passport.prisma +75 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from '@rudderjs/contracts';
|
|
2
|
+
/**
|
|
3
|
+
* Middleware that requires specific OAuth scopes on the Bearer token.
|
|
4
|
+
* Must be used after BearerMiddleware or RequireBearer.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* router.get('/admin', [RequireBearer(), scope('admin')], handler)
|
|
8
|
+
* router.post('/orders', [RequireBearer(), scope('write', 'place-orders')], handler)
|
|
9
|
+
*/
|
|
10
|
+
export declare function scope(...requiredScopes: string[]): MiddlewareHandler;
|
|
11
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/middleware/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,GAAG,cAAc,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAiCpE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware that requires specific OAuth scopes on the Bearer token.
|
|
3
|
+
* Must be used after BearerMiddleware or RequireBearer.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* router.get('/admin', [RequireBearer(), scope('admin')], handler)
|
|
7
|
+
* router.post('/orders', [RequireBearer(), scope('write', 'place-orders')], handler)
|
|
8
|
+
*/
|
|
9
|
+
export function scope(...requiredScopes) {
|
|
10
|
+
return async function ScopeMiddleware(req, res, next) {
|
|
11
|
+
const raw = req.raw;
|
|
12
|
+
const tokenScopes = raw['__passport_scopes'];
|
|
13
|
+
if (!tokenScopes) {
|
|
14
|
+
res.status(403).json({
|
|
15
|
+
error: 'insufficient_scope',
|
|
16
|
+
message: 'Token does not have the required scopes.',
|
|
17
|
+
required: requiredScopes,
|
|
18
|
+
});
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Wildcard scope grants everything
|
|
22
|
+
if (tokenScopes.includes('*')) {
|
|
23
|
+
await next();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const missing = requiredScopes.filter(s => !tokenScopes.includes(s));
|
|
27
|
+
if (missing.length > 0) {
|
|
28
|
+
res.status(403).json({
|
|
29
|
+
error: 'insufficient_scope',
|
|
30
|
+
message: `Token is missing scope(s): ${missing.join(', ')}`,
|
|
31
|
+
required: requiredScopes,
|
|
32
|
+
missing,
|
|
33
|
+
});
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await next();
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/middleware/scope.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK,CAAC,GAAG,cAAwB;IAC/C,OAAO,KAAK,UAAU,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI;QAClD,MAAM,GAAG,GAAG,GAAG,CAAC,GAA8B,CAAA;QAC9C,MAAM,WAAW,GAAG,GAAG,CAAC,mBAAmB,CAAyB,CAAA;QAEpE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,oBAAoB;gBAC3B,OAAO,EAAE,0CAA0C;gBACnD,QAAQ,EAAE,cAAc;aACzB,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,mCAAmC;QACnC,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,EAAE,CAAA;YACZ,OAAM;QACR,CAAC;QAED,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QACpE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,oBAAoB;gBAC3B,OAAO,EAAE,8BAA8B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBAC3D,QAAQ,EAAE,cAAc;gBACxB,OAAO;aACR,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,MAAM,IAAI,EAAE,CAAA;IACd,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export declare class AccessToken extends Model {
|
|
3
|
+
static table: string;
|
|
4
|
+
static fillable: string[];
|
|
5
|
+
userId: string | null;
|
|
6
|
+
clientId: string;
|
|
7
|
+
name: string | null;
|
|
8
|
+
revoked: boolean;
|
|
9
|
+
expiresAt: Date;
|
|
10
|
+
/** Parsed scopes array. */
|
|
11
|
+
getScopes(): string[];
|
|
12
|
+
/** Check if the token has a specific scope. */
|
|
13
|
+
can(scope: string): boolean;
|
|
14
|
+
/** Check if the token is missing a specific scope. */
|
|
15
|
+
cant(scope: string): boolean;
|
|
16
|
+
/** Revoke this token. */
|
|
17
|
+
revoke(): Promise<void>;
|
|
18
|
+
/** Whether this token has expired. */
|
|
19
|
+
isExpired(): boolean;
|
|
20
|
+
/** Whether this token is valid (not revoked and not expired). */
|
|
21
|
+
isValid(): boolean;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=AccessToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessToken.d.ts","sourceRoot":"","sources":["../../src/models/AccessToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,WAAY,SAAQ,KAAK;IACpC,OAAgB,KAAK,SAAwB;IAE7C,OAAgB,QAAQ,WAAmE;IAEnF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,IAAI,CAAA;IAEvB,2BAA2B;IAC3B,SAAS,IAAI,MAAM,EAAE;IAMrB,+CAA+C;IAC/C,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAK3B,sDAAsD;IACtD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI5B,yBAAyB;IACnB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,sCAAsC;IACtC,SAAS,IAAI,OAAO;IAIpB,iEAAiE;IACjE,OAAO,IAAI,OAAO;CAGnB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export class AccessToken extends Model {
|
|
3
|
+
static table = 'oauth_access_tokens';
|
|
4
|
+
static fillable = ['userId', 'clientId', 'name', 'scopes', 'revoked', 'expiresAt'];
|
|
5
|
+
/** Parsed scopes array. */
|
|
6
|
+
getScopes() {
|
|
7
|
+
const raw = this['scopes'];
|
|
8
|
+
if (typeof raw === 'string')
|
|
9
|
+
return JSON.parse(raw);
|
|
10
|
+
return raw ?? [];
|
|
11
|
+
}
|
|
12
|
+
/** Check if the token has a specific scope. */
|
|
13
|
+
can(scope) {
|
|
14
|
+
const scopes = this.getScopes();
|
|
15
|
+
return scopes.includes('*') || scopes.includes(scope);
|
|
16
|
+
}
|
|
17
|
+
/** Check if the token is missing a specific scope. */
|
|
18
|
+
cant(scope) {
|
|
19
|
+
return !this.can(scope);
|
|
20
|
+
}
|
|
21
|
+
/** Revoke this token. */
|
|
22
|
+
async revoke() {
|
|
23
|
+
this.revoked = true;
|
|
24
|
+
await this.constructor.update(this.id, { revoked: true });
|
|
25
|
+
}
|
|
26
|
+
/** Whether this token has expired. */
|
|
27
|
+
isExpired() {
|
|
28
|
+
return new Date(this.expiresAt).getTime() <= Date.now();
|
|
29
|
+
}
|
|
30
|
+
/** Whether this token is valid (not revoked and not expired). */
|
|
31
|
+
isValid() {
|
|
32
|
+
return !this.revoked && !this.isExpired();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=AccessToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessToken.js","sourceRoot":"","sources":["../../src/models/AccessToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,MAAM,CAAU,KAAK,GAAG,qBAAqB,CAAA;IAE7C,MAAM,CAAU,QAAQ,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAQ3F,2BAA2B;IAC3B,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,+CAA+C;IAC/C,GAAG,CAAC,KAAa;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvD,CAAC;IAED,sDAAsD;IACtD,IAAI,CAAC,KAAa;QAChB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACzB,CAAC;IAED,yBAAyB;IACzB,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,MAAO,IAAI,CAAC,WAAkC,CAAC,MAAM,CAAE,IAAY,CAAC,EAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAS,CAAC,CAAA;IAC7G,CAAC;IAED,sCAAsC;IACtC,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC;IAED,iEAAiE;IACjE,OAAO;QACL,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAA;IAC3C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export declare class AuthCode extends Model {
|
|
3
|
+
static table: string;
|
|
4
|
+
static fillable: string[];
|
|
5
|
+
userId: string;
|
|
6
|
+
clientId: string;
|
|
7
|
+
revoked: boolean;
|
|
8
|
+
expiresAt: Date;
|
|
9
|
+
codeChallenge: string | null;
|
|
10
|
+
codeChallengeMethod: string | null;
|
|
11
|
+
/** Parsed scopes array. */
|
|
12
|
+
getScopes(): string[];
|
|
13
|
+
/** Whether this auth code has expired. */
|
|
14
|
+
isExpired(): boolean;
|
|
15
|
+
/** Whether PKCE was used. */
|
|
16
|
+
isPkce(): boolean;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=AuthCode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthCode.d.ts","sourceRoot":"","sources":["../../src/models/AuthCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,QAAS,SAAQ,KAAK;IACjC,OAAgB,KAAK,SAAqB;IAE1C,OAAgB,QAAQ,WAAmG;IAEnH,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,IAAI,CAAA;IACf,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAE1C,2BAA2B;IAC3B,SAAS,IAAI,MAAM,EAAE;IAMrB,0CAA0C;IAC1C,SAAS,IAAI,OAAO;IAIpB,6BAA6B;IAC7B,MAAM,IAAI,OAAO;CAGlB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export class AuthCode extends Model {
|
|
3
|
+
static table = 'oauth_auth_codes';
|
|
4
|
+
static fillable = ['userId', 'clientId', 'scopes', 'revoked', 'expiresAt', 'codeChallenge', 'codeChallengeMethod'];
|
|
5
|
+
/** Parsed scopes array. */
|
|
6
|
+
getScopes() {
|
|
7
|
+
const raw = this['scopes'];
|
|
8
|
+
if (typeof raw === 'string')
|
|
9
|
+
return JSON.parse(raw);
|
|
10
|
+
return raw ?? [];
|
|
11
|
+
}
|
|
12
|
+
/** Whether this auth code has expired. */
|
|
13
|
+
isExpired() {
|
|
14
|
+
return new Date(this.expiresAt).getTime() <= Date.now();
|
|
15
|
+
}
|
|
16
|
+
/** Whether PKCE was used. */
|
|
17
|
+
isPkce() {
|
|
18
|
+
return this.codeChallenge !== null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=AuthCode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthCode.js","sourceRoot":"","sources":["../../src/models/AuthCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,MAAM,CAAU,KAAK,GAAG,kBAAkB,CAAA;IAE1C,MAAM,CAAU,QAAQ,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,qBAAqB,CAAC,CAAA;IAS3H,2BAA2B;IAC3B,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,0CAA0C;IAC1C,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC;IAED,6BAA6B;IAC7B,MAAM;QACJ,OAAO,IAAI,CAAC,aAAa,KAAK,IAAI,CAAA;IACpC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export declare class DeviceCode extends Model {
|
|
3
|
+
static table: string;
|
|
4
|
+
static fillable: string[];
|
|
5
|
+
clientId: string;
|
|
6
|
+
userCode: string;
|
|
7
|
+
deviceCode: string;
|
|
8
|
+
userId: string | null;
|
|
9
|
+
approved: boolean | null;
|
|
10
|
+
expiresAt: Date;
|
|
11
|
+
lastPolledAt: Date | null;
|
|
12
|
+
/** Parsed scopes array. */
|
|
13
|
+
getScopes(): string[];
|
|
14
|
+
/** Whether this device code has expired. */
|
|
15
|
+
isExpired(): boolean;
|
|
16
|
+
/** Whether the user has approved this device. */
|
|
17
|
+
isApproved(): boolean;
|
|
18
|
+
/** Whether the user has denied this device. */
|
|
19
|
+
isDenied(): boolean;
|
|
20
|
+
/** Whether the user hasn't responded yet. */
|
|
21
|
+
isPending(): boolean;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=DeviceCode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceCode.d.ts","sourceRoot":"","sources":["../../src/models/DeviceCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,UAAW,SAAQ,KAAK;IACnC,OAAgB,KAAK,SAAuB;IAE5C,OAAgB,QAAQ,WAAsG;IAEtH,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,IAAI,CAAA;IACf,YAAY,EAAE,IAAI,GAAG,IAAI,CAAA;IAEjC,2BAA2B;IAC3B,SAAS,IAAI,MAAM,EAAE;IAMrB,4CAA4C;IAC5C,SAAS,IAAI,OAAO;IAIpB,iDAAiD;IACjD,UAAU,IAAI,OAAO;IAIrB,+CAA+C;IAC/C,QAAQ,IAAI,OAAO;IAInB,6CAA6C;IAC7C,SAAS,IAAI,OAAO;CAGrB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export class DeviceCode extends Model {
|
|
3
|
+
static table = 'oauth_device_codes';
|
|
4
|
+
static fillable = ['clientId', 'userCode', 'deviceCode', 'scopes', 'userId', 'approved', 'expiresAt', 'lastPolledAt'];
|
|
5
|
+
/** Parsed scopes array. */
|
|
6
|
+
getScopes() {
|
|
7
|
+
const raw = this['scopes'];
|
|
8
|
+
if (typeof raw === 'string')
|
|
9
|
+
return JSON.parse(raw);
|
|
10
|
+
return raw ?? [];
|
|
11
|
+
}
|
|
12
|
+
/** Whether this device code has expired. */
|
|
13
|
+
isExpired() {
|
|
14
|
+
return new Date(this.expiresAt).getTime() <= Date.now();
|
|
15
|
+
}
|
|
16
|
+
/** Whether the user has approved this device. */
|
|
17
|
+
isApproved() {
|
|
18
|
+
return this.approved === true;
|
|
19
|
+
}
|
|
20
|
+
/** Whether the user has denied this device. */
|
|
21
|
+
isDenied() {
|
|
22
|
+
return this.approved === false;
|
|
23
|
+
}
|
|
24
|
+
/** Whether the user hasn't responded yet. */
|
|
25
|
+
isPending() {
|
|
26
|
+
return this.approved === null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=DeviceCode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceCode.js","sourceRoot":"","sources":["../../src/models/DeviceCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,MAAM,CAAU,KAAK,GAAG,oBAAoB,CAAA;IAE5C,MAAM,CAAU,QAAQ,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAA;IAU9H,2BAA2B;IAC3B,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,4CAA4C;IAC5C,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC;IAED,iDAAiD;IACjD,UAAU;QACR,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA;IAC/B,CAAC;IAED,+CAA+C;IAC/C,QAAQ;QACN,OAAO,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAA;IAChC,CAAC;IAED,6CAA6C;IAC7C,SAAS;QACP,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAA;IAC/B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export declare class OAuthClient extends Model {
|
|
3
|
+
static table: string;
|
|
4
|
+
static fillable: string[];
|
|
5
|
+
secret: string | null;
|
|
6
|
+
name: string;
|
|
7
|
+
confidential: boolean;
|
|
8
|
+
revoked: boolean;
|
|
9
|
+
/** Parsed redirect URIs. */
|
|
10
|
+
getRedirectUris(): string[];
|
|
11
|
+
/** Parsed grant types. */
|
|
12
|
+
getGrantTypes(): string[];
|
|
13
|
+
/** Parsed scopes. */
|
|
14
|
+
getScopes(): string[];
|
|
15
|
+
/** Check if client supports a specific grant type. */
|
|
16
|
+
hasGrantType(type: string): boolean;
|
|
17
|
+
/** Check if a redirect URI is registered for this client. */
|
|
18
|
+
hasRedirectUri(uri: string): boolean;
|
|
19
|
+
/** Whether this is a first-party (non-confidential / PKCE) client. */
|
|
20
|
+
isPublic(): boolean;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=OAuthClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthClient.d.ts","sourceRoot":"","sources":["../../src/models/OAuthClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAU,MAAM,eAAe,CAAA;AAE7C,qBAAa,WAAY,SAAQ,KAAK;IACpC,OAAgB,KAAK,SAAkB;IAEvC,OAAgB,QAAQ,WAA6E;IAG7F,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAErB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAExB,4BAA4B;IAC5B,eAAe,IAAI,MAAM,EAAE;IAM3B,0BAA0B;IAC1B,aAAa,IAAI,MAAM,EAAE;IAMzB,qBAAqB;IACrB,SAAS,IAAI,MAAM,EAAE;IAMrB,sDAAsD;IACtD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,6DAA6D;IAC7D,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIpC,sEAAsE;IACtE,QAAQ,IAAI,OAAO;CAGpB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Model, Hidden } from '@rudderjs/orm';
|
|
11
|
+
export class OAuthClient extends Model {
|
|
12
|
+
static table = 'oauth_clients';
|
|
13
|
+
static fillable = ['name', 'secret', 'redirectUris', 'grantTypes', 'scopes', 'confidential'];
|
|
14
|
+
/** Parsed redirect URIs. */
|
|
15
|
+
getRedirectUris() {
|
|
16
|
+
const raw = this['redirectUris'];
|
|
17
|
+
if (typeof raw === 'string')
|
|
18
|
+
return JSON.parse(raw);
|
|
19
|
+
return raw ?? [];
|
|
20
|
+
}
|
|
21
|
+
/** Parsed grant types. */
|
|
22
|
+
getGrantTypes() {
|
|
23
|
+
const raw = this['grantTypes'];
|
|
24
|
+
if (typeof raw === 'string')
|
|
25
|
+
return JSON.parse(raw);
|
|
26
|
+
return raw ?? [];
|
|
27
|
+
}
|
|
28
|
+
/** Parsed scopes. */
|
|
29
|
+
getScopes() {
|
|
30
|
+
const raw = this['scopes'];
|
|
31
|
+
if (typeof raw === 'string')
|
|
32
|
+
return JSON.parse(raw);
|
|
33
|
+
return raw ?? [];
|
|
34
|
+
}
|
|
35
|
+
/** Check if client supports a specific grant type. */
|
|
36
|
+
hasGrantType(type) {
|
|
37
|
+
return this.getGrantTypes().includes(type);
|
|
38
|
+
}
|
|
39
|
+
/** Check if a redirect URI is registered for this client. */
|
|
40
|
+
hasRedirectUri(uri) {
|
|
41
|
+
return this.getRedirectUris().includes(uri);
|
|
42
|
+
}
|
|
43
|
+
/** Whether this is a first-party (non-confidential / PKCE) client. */
|
|
44
|
+
isPublic() {
|
|
45
|
+
return !this.confidential;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
__decorate([
|
|
49
|
+
Hidden,
|
|
50
|
+
__metadata("design:type", Object)
|
|
51
|
+
], OAuthClient.prototype, "secret", void 0);
|
|
52
|
+
//# sourceMappingURL=OAuthClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthClient.js","sourceRoot":"","sources":["../../src/models/OAuthClient.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,MAAM,CAAU,KAAK,GAAG,eAAe,CAAA;IAEvC,MAAM,CAAU,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAA;IASrG,4BAA4B;IAC5B,eAAe;QACb,MAAM,GAAG,GAAI,IAA2C,CAAC,cAAc,CAAC,CAAA;QACxE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,0BAA0B;IAC1B,aAAa;QACX,MAAM,GAAG,GAAI,IAA2C,CAAC,YAAY,CAAC,CAAA;QACtE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,qBAAqB;IACrB,SAAS;QACP,MAAM,GAAG,GAAI,IAA2C,CAAC,QAAQ,CAAC,CAAA;QAClE,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAA;QAC/D,OAAQ,GAAgB,IAAI,EAAE,CAAA;IAChC,CAAC;IAED,sDAAsD;IACtD,YAAY,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC5C,CAAC;IAED,6DAA6D;IAC7D,cAAc,CAAC,GAAW;QACxB,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IAC7C,CAAC;IAED,sEAAsE;IACtE,QAAQ;QACN,OAAO,CAAC,IAAI,CAAC,YAAY,CAAA;IAC3B,CAAC;;AAxCO;IADP,MAAM;;2CACsB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export declare class RefreshToken extends Model {
|
|
3
|
+
static table: string;
|
|
4
|
+
static fillable: string[];
|
|
5
|
+
accessTokenId: string;
|
|
6
|
+
revoked: boolean;
|
|
7
|
+
expiresAt: Date;
|
|
8
|
+
/** Revoke this refresh token. */
|
|
9
|
+
revoke(): Promise<void>;
|
|
10
|
+
/** Whether this token has expired. */
|
|
11
|
+
isExpired(): boolean;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=RefreshToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RefreshToken.d.ts","sourceRoot":"","sources":["../../src/models/RefreshToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,qBAAa,YAAa,SAAQ,KAAK;IACrC,OAAgB,KAAK,SAAyB;IAE9C,OAAgB,QAAQ,WAA4C;IAE5D,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,IAAI,CAAA;IAEvB,iCAAiC;IAC3B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,sCAAsC;IACtC,SAAS,IAAI,OAAO;CAGrB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Model } from '@rudderjs/orm';
|
|
2
|
+
export class RefreshToken extends Model {
|
|
3
|
+
static table = 'oauth_refresh_tokens';
|
|
4
|
+
static fillable = ['accessTokenId', 'revoked', 'expiresAt'];
|
|
5
|
+
/** Revoke this refresh token. */
|
|
6
|
+
async revoke() {
|
|
7
|
+
this.revoked = true;
|
|
8
|
+
await this.constructor.update(this.id, { revoked: true });
|
|
9
|
+
}
|
|
10
|
+
/** Whether this token has expired. */
|
|
11
|
+
isExpired() {
|
|
12
|
+
return new Date(this.expiresAt).getTime() <= Date.now();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=RefreshToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RefreshToken.js","sourceRoot":"","sources":["../../src/models/RefreshToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,MAAM,CAAU,KAAK,GAAG,sBAAsB,CAAA;IAE9C,MAAM,CAAU,QAAQ,GAAG,CAAC,eAAe,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAMpE,iCAAiC;IACjC,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,MAAO,IAAI,CAAC,WAAmC,CAAC,MAAM,CAAE,IAAY,CAAC,EAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAS,CAAC,CAAA;IAC9G,CAAC;IAED,sCAAsC;IACtC,SAAS;QACP,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA;IACzD,CAAC"}
|
package/dist/token.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface JwtHeader {
|
|
2
|
+
alg: 'RS256';
|
|
3
|
+
typ: 'JWT';
|
|
4
|
+
}
|
|
5
|
+
export interface JwtPayload {
|
|
6
|
+
/** Token ID */
|
|
7
|
+
jti: string;
|
|
8
|
+
/** Subject — user ID (null for client credentials) */
|
|
9
|
+
sub: string | null;
|
|
10
|
+
/** Audience — client ID */
|
|
11
|
+
aud: string;
|
|
12
|
+
/** Issued at (seconds) */
|
|
13
|
+
iat: number;
|
|
14
|
+
/** Expiration (seconds) */
|
|
15
|
+
exp: number;
|
|
16
|
+
/** Scopes */
|
|
17
|
+
scopes: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create a signed JWT using RSA-SHA256.
|
|
21
|
+
* Uses the private key from Passport configuration.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createToken(payload: {
|
|
24
|
+
tokenId: string;
|
|
25
|
+
userId: string | null;
|
|
26
|
+
clientId: string;
|
|
27
|
+
scopes: string[];
|
|
28
|
+
expiresAt: Date;
|
|
29
|
+
}): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Verify and decode a JWT using RSA-SHA256.
|
|
32
|
+
* Returns the payload if valid, throws if invalid.
|
|
33
|
+
*/
|
|
34
|
+
export declare function verifyToken(jwt: string): Promise<JwtPayload>;
|
|
35
|
+
/**
|
|
36
|
+
* Decode a JWT payload without verifying the signature.
|
|
37
|
+
* Useful for reading token metadata (e.g., jti for revocation check).
|
|
38
|
+
*/
|
|
39
|
+
export declare function decodeToken(jwt: string): JwtPayload;
|
|
40
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,OAAO,CAAA;IACZ,GAAG,EAAE,KAAK,CAAA;CACX;AAED,MAAM,WAAW,UAAU;IACzB,eAAe;IACf,GAAG,EAAM,MAAM,CAAA;IACf,sDAAsD;IACtD,GAAG,EAAM,MAAM,GAAG,IAAI,CAAA;IACtB,2BAA2B;IAC3B,GAAG,EAAM,MAAM,CAAA;IACf,0BAA0B;IAC1B,GAAG,EAAM,MAAM,CAAA;IACf,2BAA2B;IAC3B,GAAG,EAAM,MAAM,CAAA;IACf,aAAa;IACb,MAAM,EAAG,MAAM,EAAE,CAAA;CAClB;AAeD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE;IACzC,OAAO,EAAG,MAAM,CAAA;IAChB,MAAM,EAAI,MAAM,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAI,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,IAAI,CAAA;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BlB;AAID;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA+BlE;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAMnD"}
|
package/dist/token.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Passport } from './Passport.js';
|
|
2
|
+
// ─── Helpers ──────────────────────────────────────────────
|
|
3
|
+
function base64url(data) {
|
|
4
|
+
const buf = typeof data === 'string' ? Buffer.from(data, 'utf8') : data;
|
|
5
|
+
return buf.toString('base64url');
|
|
6
|
+
}
|
|
7
|
+
function base64urlDecode(str) {
|
|
8
|
+
return Buffer.from(str, 'base64url').toString('utf8');
|
|
9
|
+
}
|
|
10
|
+
// ─── Create JWT ───────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Create a signed JWT using RSA-SHA256.
|
|
13
|
+
* Uses the private key from Passport configuration.
|
|
14
|
+
*/
|
|
15
|
+
export async function createToken(payload) {
|
|
16
|
+
const { createSign } = await import('node:crypto');
|
|
17
|
+
const { privateKey } = await Passport.keys();
|
|
18
|
+
const header = { alg: 'RS256', typ: 'JWT' };
|
|
19
|
+
const now = Math.floor(Date.now() / 1000);
|
|
20
|
+
const jwtPayload = {
|
|
21
|
+
jti: payload.tokenId,
|
|
22
|
+
sub: payload.userId,
|
|
23
|
+
aud: payload.clientId,
|
|
24
|
+
iat: now,
|
|
25
|
+
exp: Math.floor(payload.expiresAt.getTime() / 1000),
|
|
26
|
+
scopes: payload.scopes,
|
|
27
|
+
};
|
|
28
|
+
const segments = [
|
|
29
|
+
base64url(JSON.stringify(header)),
|
|
30
|
+
base64url(JSON.stringify(jwtPayload)),
|
|
31
|
+
];
|
|
32
|
+
const signingInput = segments.join('.');
|
|
33
|
+
const sign = createSign('RSA-SHA256');
|
|
34
|
+
sign.update(signingInput);
|
|
35
|
+
const signature = sign.sign(privateKey, 'base64url');
|
|
36
|
+
return `${signingInput}.${signature}`;
|
|
37
|
+
}
|
|
38
|
+
// ─── Verify JWT ───────────────────────────────────────────
|
|
39
|
+
/**
|
|
40
|
+
* Verify and decode a JWT using RSA-SHA256.
|
|
41
|
+
* Returns the payload if valid, throws if invalid.
|
|
42
|
+
*/
|
|
43
|
+
export async function verifyToken(jwt) {
|
|
44
|
+
const { createVerify } = await import('node:crypto');
|
|
45
|
+
const { publicKey } = await Passport.keys();
|
|
46
|
+
const parts = jwt.split('.');
|
|
47
|
+
if (parts.length !== 3) {
|
|
48
|
+
throw new Error('Invalid JWT: expected 3 segments');
|
|
49
|
+
}
|
|
50
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
51
|
+
// Verify signature
|
|
52
|
+
const signingInput = `${headerB64}.${payloadB64}`;
|
|
53
|
+
const verify = createVerify('RSA-SHA256');
|
|
54
|
+
verify.update(signingInput);
|
|
55
|
+
const valid = verify.verify(publicKey, signatureB64, 'base64url');
|
|
56
|
+
if (!valid) {
|
|
57
|
+
throw new Error('Invalid JWT: signature verification failed');
|
|
58
|
+
}
|
|
59
|
+
// Decode payload
|
|
60
|
+
const payload = JSON.parse(base64urlDecode(payloadB64));
|
|
61
|
+
// Check expiration
|
|
62
|
+
const now = Math.floor(Date.now() / 1000);
|
|
63
|
+
if (payload.exp <= now) {
|
|
64
|
+
throw new Error('Invalid JWT: token has expired');
|
|
65
|
+
}
|
|
66
|
+
return payload;
|
|
67
|
+
}
|
|
68
|
+
// ─── Decode without verification (for inspection) ─────────
|
|
69
|
+
/**
|
|
70
|
+
* Decode a JWT payload without verifying the signature.
|
|
71
|
+
* Useful for reading token metadata (e.g., jti for revocation check).
|
|
72
|
+
*/
|
|
73
|
+
export function decodeToken(jwt) {
|
|
74
|
+
const parts = jwt.split('.');
|
|
75
|
+
if (parts.length !== 3) {
|
|
76
|
+
throw new Error('Invalid JWT: expected 3 segments');
|
|
77
|
+
}
|
|
78
|
+
return JSON.parse(base64urlDecode(parts[1]));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rudderjs/passport",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"rudderjs": {
|
|
5
|
+
"provider": "PassportProvider",
|
|
6
|
+
"stage": "infrastructure",
|
|
7
|
+
"depends": [
|
|
8
|
+
"@rudderjs/auth",
|
|
9
|
+
"@rudderjs/orm-prisma"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/rudderjs/rudder",
|
|
16
|
+
"directory": "packages/passport"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"schema"
|
|
22
|
+
],
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@rudderjs/core": "0.0.8",
|
|
33
|
+
"@rudderjs/contracts": "0.0.3",
|
|
34
|
+
"@rudderjs/orm": "0.0.6"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20.0.0",
|
|
38
|
+
"typescript": "^5.4.0",
|
|
39
|
+
"tsx": "^4.0.0",
|
|
40
|
+
"@rudderjs/rudder": "0.0.2"
|
|
41
|
+
},
|
|
42
|
+
"author": "Suleiman Shahbari",
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.build.json",
|
|
45
|
+
"dev": "tsc -p tsconfig.build.json --watch",
|
|
46
|
+
"typecheck": "tsc --noEmit",
|
|
47
|
+
"lint": "eslint src",
|
|
48
|
+
"clean": "rm -rf dist",
|
|
49
|
+
"test": "tsc -p tsconfig.test.json && node --test dist-test/index.test.js; EXIT=$?; rm -rf dist-test; exit $EXIT"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
model OAuthClient {
|
|
2
|
+
id String @id @default(cuid())
|
|
3
|
+
name String
|
|
4
|
+
secret String?
|
|
5
|
+
redirectUris String @default("[]")
|
|
6
|
+
grantTypes String @default("[\"authorization_code\"]")
|
|
7
|
+
scopes String @default("[]")
|
|
8
|
+
confidential Boolean @default(true)
|
|
9
|
+
revoked Boolean @default(false)
|
|
10
|
+
createdAt DateTime @default(now())
|
|
11
|
+
updatedAt DateTime @updatedAt
|
|
12
|
+
|
|
13
|
+
accessTokens OAuthAccessToken[]
|
|
14
|
+
authCodes OAuthAuthCode[]
|
|
15
|
+
|
|
16
|
+
@@map("oauth_clients")
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
model OAuthAccessToken {
|
|
20
|
+
id String @id @default(cuid())
|
|
21
|
+
userId String?
|
|
22
|
+
clientId String
|
|
23
|
+
name String?
|
|
24
|
+
scopes String @default("[]")
|
|
25
|
+
revoked Boolean @default(false)
|
|
26
|
+
expiresAt DateTime
|
|
27
|
+
createdAt DateTime @default(now())
|
|
28
|
+
|
|
29
|
+
client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
|
30
|
+
refreshToken OAuthRefreshToken?
|
|
31
|
+
|
|
32
|
+
@@index([userId])
|
|
33
|
+
@@map("oauth_access_tokens")
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
model OAuthRefreshToken {
|
|
37
|
+
id String @id @default(cuid())
|
|
38
|
+
accessTokenId String @unique
|
|
39
|
+
revoked Boolean @default(false)
|
|
40
|
+
expiresAt DateTime
|
|
41
|
+
|
|
42
|
+
accessToken OAuthAccessToken @relation(fields: [accessTokenId], references: [id], onDelete: Cascade)
|
|
43
|
+
|
|
44
|
+
@@map("oauth_refresh_tokens")
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
model OAuthAuthCode {
|
|
48
|
+
id String @id @default(cuid())
|
|
49
|
+
userId String
|
|
50
|
+
clientId String
|
|
51
|
+
scopes String @default("[]")
|
|
52
|
+
revoked Boolean @default(false)
|
|
53
|
+
expiresAt DateTime
|
|
54
|
+
codeChallenge String?
|
|
55
|
+
codeChallengeMethod String?
|
|
56
|
+
|
|
57
|
+
client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
|
58
|
+
|
|
59
|
+
@@map("oauth_auth_codes")
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
model OAuthDeviceCode {
|
|
63
|
+
id String @id @default(cuid())
|
|
64
|
+
clientId String
|
|
65
|
+
userCode String @unique
|
|
66
|
+
deviceCode String @unique
|
|
67
|
+
scopes String @default("[]")
|
|
68
|
+
userId String?
|
|
69
|
+
approved Boolean?
|
|
70
|
+
expiresAt DateTime
|
|
71
|
+
lastPolledAt DateTime?
|
|
72
|
+
createdAt DateTime @default(now())
|
|
73
|
+
|
|
74
|
+
@@map("oauth_device_codes")
|
|
75
|
+
}
|