@memberjunction/auth-providers 5.39.0 → 5.40.0
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/AuthProviderFactory.d.ts +1 -0
- package/dist/AuthProviderFactory.d.ts.map +1 -1
- package/dist/AuthProviderFactory.js +1 -0
- package/dist/AuthProviderFactory.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/MagicLinkProvider.d.ts +26 -0
- package/dist/providers/MagicLinkProvider.d.ts.map +1 -0
- package/dist/providers/MagicLinkProvider.js +53 -0
- package/dist/providers/MagicLinkProvider.js.map +1 -0
- package/package.json +3 -3
- package/src/AuthProviderFactory.ts +1 -0
- package/src/index.ts +1 -0
- package/src/providers/MagicLinkProvider.ts +44 -0
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @memberjunction/auth-providers
|
|
2
2
|
|
|
3
|
+
## 5.40.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 43e6c0f: MJ-issued magic-link sessions for external, app-scoped users: passwordless, single-use (or multi-use) invite links that sign external users into MJExplorer confined to one application and a per-link role. MJ issues and validates its own RS256 session tokens (published via JWKS, accepted by the standard auth-provider path), so there's no external IdP dependency or per-user IdP cost. Invite scope (app, role, expiry, max uses) is configured per link, with support for per-invite app/role, resource-scoped RLS sharing, and anonymous sessions — a shared Anonymous principal whose scope rides per-session JWT claims rather than DB roles, so concurrent anonymous visitors can't accrete privileges.
|
|
8
|
+
|
|
9
|
+
Also includes two framework changes made along the way:
|
|
10
|
+
- **RunView server-cache RLS fix:** the cache fingerprint now incorporates the per-user Row-Level-Security where-clause, so an RLS-scoped read can no longer be served an unscoped cached result. No-op for users without an RLS filter (byte-identical fingerprint), so normal caching is untouched.
|
|
11
|
+
- **BaseEngine degrades gracefully under restricted roles:** a config load that fails because the current user lacks Read permission is now treated as a permanent condition — the property loads empty and the engine is marked loaded — instead of looping on "not marking as loaded", which previously hung the MJExplorer shell for least-privilege users (e.g. magic-link guests). Only genuinely transient failures (network, server restart) keep retrying.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [804f9f6]
|
|
16
|
+
- Updated dependencies [73bb233]
|
|
17
|
+
- Updated dependencies [43e6c0f]
|
|
18
|
+
- @memberjunction/core@5.40.0
|
|
19
|
+
- @memberjunction/global@5.40.0
|
|
20
|
+
|
|
3
21
|
## 5.39.0
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -6,6 +6,7 @@ import './providers/MSALProvider.js';
|
|
|
6
6
|
import './providers/OktaProvider.js';
|
|
7
7
|
import './providers/CognitoProvider.js';
|
|
8
8
|
import './providers/GoogleProvider.js';
|
|
9
|
+
import './providers/MagicLinkProvider.js';
|
|
9
10
|
/**
|
|
10
11
|
* Factory and registry for managing authentication providers
|
|
11
12
|
* Combines provider creation and lifecycle management in a single class
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProviderFactory.d.ts","sourceRoot":"","sources":["../src/AuthProviderFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAY,aAAa,EAAc,MAAM,wBAAwB,CAAC;AAG7E,OAAO,8BAA8B,CAAC;AACtC,OAAO,6BAA6B,CAAC;AACrC,OAAO,6BAA6B,CAAC;AACrC,OAAO,gCAAgC,CAAC;AACxC,OAAO,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthProviderFactory.d.ts","sourceRoot":"","sources":["../src/AuthProviderFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAY,aAAa,EAAc,MAAM,wBAAwB,CAAC;AAG7E,OAAO,8BAA8B,CAAC;AACtC,OAAO,6BAA6B,CAAC;AACrC,OAAO,6BAA6B,CAAC;AACrC,OAAO,gCAAgC,CAAC;AACxC,OAAO,+BAA+B,CAAC;AACvC,OAAO,kCAAkC,CAAC;AAE1C;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,aAAa,CAAC,mBAAmB,CAAC;IACzE,OAAO,CAAC,SAAS,CAAyC;IAC1D;;;;;;OAMG;IACH,OAAO,CAAC,WAAW,CAA6F;IAChH;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAAiG;;IAMzH;;OAEG;IACH,WAAkB,QAAQ,IAAI,mBAAmB,CAEhD;IAED;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,kBAAkB,GAAG,aAAa;IAsBhE;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAcvC;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAmBtD;;;;;;OAMG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE;IAqB/C;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIlD;;OAEG;IACH,eAAe,IAAI,aAAa,EAAE;IAIlC;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,MAAM,CAAC,0BAA0B,IAAI,MAAM,EAAE;IAW7C;;OAEG;IACH,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CASvD"}
|
|
@@ -6,6 +6,7 @@ import './providers/MSALProvider.js';
|
|
|
6
6
|
import './providers/OktaProvider.js';
|
|
7
7
|
import './providers/CognitoProvider.js';
|
|
8
8
|
import './providers/GoogleProvider.js';
|
|
9
|
+
import './providers/MagicLinkProvider.js';
|
|
9
10
|
/**
|
|
10
11
|
* Factory and registry for managing authentication providers
|
|
11
12
|
* Combines provider creation and lifecycle management in a single class
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProviderFactory.js","sourceRoot":"","sources":["../src/AuthProviderFactory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAE7E,gDAAgD;AAChD,OAAO,8BAA8B,CAAC;AACtC,OAAO,6BAA6B,CAAC;AACrC,OAAO,6BAA6B,CAAC;AACrC,OAAO,gCAAgC,CAAC;AACxC,OAAO,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"AuthProviderFactory.js","sourceRoot":"","sources":["../src/AuthProviderFactory.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export { IAuthProvider } from './IAuthProvider.js';
|
|
|
2
2
|
export { BaseAuthProvider } from './BaseAuthProvider.js';
|
|
3
3
|
export { AuthProviderFactory } from './AuthProviderFactory.js';
|
|
4
4
|
export { TokenExpiredError } from './tokenExpiredError.js';
|
|
5
|
+
export { MagicLinkProvider } from './providers/MagicLinkProvider.js';
|
|
5
6
|
export type { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { BaseAuthProvider } from './BaseAuthProvider.js';
|
|
2
2
|
export { AuthProviderFactory } from './AuthProviderFactory.js';
|
|
3
3
|
export { TokenExpiredError } from './tokenExpiredError.js';
|
|
4
|
+
export { MagicLinkProvider } from './providers/MagicLinkProvider.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { JwtPayload } from 'jsonwebtoken';
|
|
2
|
+
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
3
|
+
import { BaseAuthProvider } from '../BaseAuthProvider.js';
|
|
4
|
+
/**
|
|
5
|
+
* Authentication provider for MemberJunction-issued magic-link session tokens.
|
|
6
|
+
*
|
|
7
|
+
* Unlike Auth0/Okta/etc., the tokens this provider validates are minted by MJ
|
|
8
|
+
* itself (RS256) when an external user redeems a magic-link invite. MJ publishes
|
|
9
|
+
* its public key at a JWKS endpoint, and this provider is registered with that
|
|
10
|
+
* endpoint as its `jwksUri` — so the standard issuer-driven JWT validation path
|
|
11
|
+
* in MJServer (`context.ts`) verifies these tokens with no special-casing.
|
|
12
|
+
*
|
|
13
|
+
* The minted tokens carry standard OIDC identity claims (`email`, `given_name`,
|
|
14
|
+
* `family_name`) plus magic-link scope claims (`mj_app_id`, `mj_role`,
|
|
15
|
+
* `mj_magic_link`). Only the identity claims are needed here; scope is enforced
|
|
16
|
+
* at provisioning time and by the assigned restricted role, not re-derived on
|
|
17
|
+
* every request.
|
|
18
|
+
*/
|
|
19
|
+
export declare class MagicLinkProvider extends BaseAuthProvider {
|
|
20
|
+
constructor(config: AuthProviderConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Extracts user identity from a MJ-issued magic-link JWT payload.
|
|
23
|
+
*/
|
|
24
|
+
extractUserInfo(payload: JwtPayload): AuthUserInfo;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=MagicLinkProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MagicLinkProvider.d.ts","sourceRoot":"","sources":["../../src/providers/MagicLinkProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,qBACa,iBAAkB,SAAQ,gBAAgB;gBACzC,MAAM,EAAE,kBAAkB;IAItC;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,YAAY;CAcnD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
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 { RegisterClass } from '@memberjunction/global';
|
|
11
|
+
import { BaseAuthProvider } from '../BaseAuthProvider.js';
|
|
12
|
+
/**
|
|
13
|
+
* Authentication provider for MemberJunction-issued magic-link session tokens.
|
|
14
|
+
*
|
|
15
|
+
* Unlike Auth0/Okta/etc., the tokens this provider validates are minted by MJ
|
|
16
|
+
* itself (RS256) when an external user redeems a magic-link invite. MJ publishes
|
|
17
|
+
* its public key at a JWKS endpoint, and this provider is registered with that
|
|
18
|
+
* endpoint as its `jwksUri` — so the standard issuer-driven JWT validation path
|
|
19
|
+
* in MJServer (`context.ts`) verifies these tokens with no special-casing.
|
|
20
|
+
*
|
|
21
|
+
* The minted tokens carry standard OIDC identity claims (`email`, `given_name`,
|
|
22
|
+
* `family_name`) plus magic-link scope claims (`mj_app_id`, `mj_role`,
|
|
23
|
+
* `mj_magic_link`). Only the identity claims are needed here; scope is enforced
|
|
24
|
+
* at provisioning time and by the assigned restricted role, not re-derived on
|
|
25
|
+
* every request.
|
|
26
|
+
*/
|
|
27
|
+
let MagicLinkProvider = class MagicLinkProvider extends BaseAuthProvider {
|
|
28
|
+
constructor(config) {
|
|
29
|
+
super(config);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Extracts user identity from a MJ-issued magic-link JWT payload.
|
|
33
|
+
*/
|
|
34
|
+
extractUserInfo(payload) {
|
|
35
|
+
const email = payload.email;
|
|
36
|
+
const fullName = payload.name;
|
|
37
|
+
const firstName = payload.given_name;
|
|
38
|
+
const lastName = payload.family_name;
|
|
39
|
+
return {
|
|
40
|
+
email,
|
|
41
|
+
firstName: firstName || fullName?.split(' ')[0],
|
|
42
|
+
lastName: lastName || fullName?.split(' ').slice(1).join(' ') || fullName?.split(' ')[0],
|
|
43
|
+
fullName: fullName || [firstName, lastName].filter(Boolean).join(' ') || undefined,
|
|
44
|
+
preferredUsername: email,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
MagicLinkProvider = __decorate([
|
|
49
|
+
RegisterClass(BaseAuthProvider, 'magic-link'),
|
|
50
|
+
__metadata("design:paramtypes", [Object])
|
|
51
|
+
], MagicLinkProvider);
|
|
52
|
+
export { MagicLinkProvider };
|
|
53
|
+
//# sourceMappingURL=MagicLinkProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MagicLinkProvider.js","sourceRoot":"","sources":["../../src/providers/MagicLinkProvider.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,gBAAgB;IACrD,YAAY,MAA0B;QACpC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,OAAmB;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAA2B,CAAC;QAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAA0B,CAAC;QACpD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAgC,CAAC;QAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAiC,CAAC;QAE3D,OAAO;YACL,KAAK;YACL,SAAS,EAAE,SAAS,IAAI,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/C,QAAQ,EAAE,QAAQ,IAAI,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACxF,QAAQ,EAAE,QAAQ,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;YAClF,iBAAiB,EAAE,KAAK;SACzB,CAAC;IACJ,CAAC;CACF,CAAA;AAtBY,iBAAiB;IAD7B,aAAa,CAAC,gBAAgB,EAAE,YAAY,CAAC;;GACjC,iBAAiB,CAsB7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/auth-providers",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.40.0",
|
|
4
4
|
"description": "Authentication provider interfaces, base classes, and implementations for MemberJunction",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"test:watch": "vitest"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@memberjunction/core": "5.
|
|
15
|
-
"@memberjunction/global": "5.
|
|
14
|
+
"@memberjunction/core": "5.40.0",
|
|
15
|
+
"@memberjunction/global": "5.40.0",
|
|
16
16
|
"graphql": "^16.12.0",
|
|
17
17
|
"jsonwebtoken": "9.0.3",
|
|
18
18
|
"jwks-rsa": "^3.2.2"
|
|
@@ -9,6 +9,7 @@ import './providers/MSALProvider.js';
|
|
|
9
9
|
import './providers/OktaProvider.js';
|
|
10
10
|
import './providers/CognitoProvider.js';
|
|
11
11
|
import './providers/GoogleProvider.js';
|
|
12
|
+
import './providers/MagicLinkProvider.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Factory and registry for managing authentication providers
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { IAuthProvider } from './IAuthProvider.js';
|
|
|
2
2
|
export { BaseAuthProvider } from './BaseAuthProvider.js';
|
|
3
3
|
export { AuthProviderFactory } from './AuthProviderFactory.js';
|
|
4
4
|
export { TokenExpiredError } from './tokenExpiredError.js';
|
|
5
|
+
export { MagicLinkProvider } from './providers/MagicLinkProvider.js';
|
|
5
6
|
|
|
6
7
|
// Re-export types consumers commonly need alongside the auth providers
|
|
7
8
|
export type { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { JwtPayload } from 'jsonwebtoken';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
4
|
+
import { BaseAuthProvider } from '../BaseAuthProvider.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Authentication provider for MemberJunction-issued magic-link session tokens.
|
|
8
|
+
*
|
|
9
|
+
* Unlike Auth0/Okta/etc., the tokens this provider validates are minted by MJ
|
|
10
|
+
* itself (RS256) when an external user redeems a magic-link invite. MJ publishes
|
|
11
|
+
* its public key at a JWKS endpoint, and this provider is registered with that
|
|
12
|
+
* endpoint as its `jwksUri` — so the standard issuer-driven JWT validation path
|
|
13
|
+
* in MJServer (`context.ts`) verifies these tokens with no special-casing.
|
|
14
|
+
*
|
|
15
|
+
* The minted tokens carry standard OIDC identity claims (`email`, `given_name`,
|
|
16
|
+
* `family_name`) plus magic-link scope claims (`mj_app_id`, `mj_role`,
|
|
17
|
+
* `mj_magic_link`). Only the identity claims are needed here; scope is enforced
|
|
18
|
+
* at provisioning time and by the assigned restricted role, not re-derived on
|
|
19
|
+
* every request.
|
|
20
|
+
*/
|
|
21
|
+
@RegisterClass(BaseAuthProvider, 'magic-link')
|
|
22
|
+
export class MagicLinkProvider extends BaseAuthProvider {
|
|
23
|
+
constructor(config: AuthProviderConfig) {
|
|
24
|
+
super(config);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Extracts user identity from a MJ-issued magic-link JWT payload.
|
|
29
|
+
*/
|
|
30
|
+
extractUserInfo(payload: JwtPayload): AuthUserInfo {
|
|
31
|
+
const email = payload.email as string | undefined;
|
|
32
|
+
const fullName = payload.name as string | undefined;
|
|
33
|
+
const firstName = payload.given_name as string | undefined;
|
|
34
|
+
const lastName = payload.family_name as string | undefined;
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
email,
|
|
38
|
+
firstName: firstName || fullName?.split(' ')[0],
|
|
39
|
+
lastName: lastName || fullName?.split(' ').slice(1).join(' ') || fullName?.split(' ')[0],
|
|
40
|
+
fullName: fullName || [firstName, lastName].filter(Boolean).join(' ') || undefined,
|
|
41
|
+
preferredUsername: email,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|