@chipmobilesdk/rn-auth 0.4.0 → 0.6.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/CHANGELOG.md +139 -0
- package/README.md +74 -14
- package/lib/commonjs/access/accessTier.js +111 -0
- package/lib/commonjs/access/accessTier.js.map +1 -0
- package/lib/commonjs/app-auth.js +13 -0
- package/lib/commonjs/app-auth.js.map +1 -0
- package/lib/commonjs/config/types.js +50 -0
- package/lib/commonjs/config/types.js.map +1 -0
- package/lib/commonjs/config/validateConfig.js +114 -0
- package/lib/commonjs/config/validateConfig.js.map +1 -0
- package/lib/commonjs/core/authMachine.js +406 -0
- package/lib/commonjs/core/authMachine.js.map +1 -0
- package/lib/commonjs/core/profile.js +59 -0
- package/lib/commonjs/core/profile.js.map +1 -0
- package/lib/commonjs/core/session.js +125 -0
- package/lib/commonjs/core/session.js.map +1 -0
- package/lib/commonjs/diagnostics/errors.js +83 -0
- package/lib/commonjs/diagnostics/errors.js.map +1 -0
- package/lib/commonjs/diagnostics/messageKeys.js +51 -0
- package/lib/commonjs/diagnostics/messageKeys.js.map +1 -0
- package/lib/commonjs/index.js +175 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/keychain.js +13 -0
- package/lib/commonjs/keychain.js.map +1 -0
- package/lib/commonjs/oidc/authClient.js +157 -0
- package/lib/commonjs/oidc/authClient.js.map +1 -0
- package/lib/commonjs/oidc/classifyError.js +65 -0
- package/lib/commonjs/oidc/classifyError.js.map +1 -0
- package/lib/commonjs/oidc/socialRouting.js +58 -0
- package/lib/commonjs/oidc/socialRouting.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/react/AuthProvider.js +37 -0
- package/lib/commonjs/react/AuthProvider.js.map +1 -0
- package/lib/commonjs/react/hooks.js +122 -0
- package/lib/commonjs/react/hooks.js.map +1 -0
- package/lib/commonjs/testing/conformance.js +148 -0
- package/lib/commonjs/testing/conformance.js.map +1 -0
- package/lib/commonjs/testing/index.js +53 -0
- package/lib/commonjs/testing/index.js.map +1 -0
- package/lib/commonjs/tokens/accessToken.js +165 -0
- package/lib/commonjs/tokens/accessToken.js.map +1 -0
- package/lib/commonjs/tokens/secureStore.js +60 -0
- package/lib/commonjs/tokens/secureStore.js.map +1 -0
- package/lib/module/access/accessTier.js +106 -0
- package/lib/module/access/accessTier.js.map +1 -0
- package/lib/module/app-auth.js +9 -0
- package/lib/module/app-auth.js.map +1 -0
- package/lib/module/config/types.js +46 -0
- package/lib/module/config/types.js.map +1 -0
- package/lib/module/config/validateConfig.js +110 -0
- package/lib/module/config/validateConfig.js.map +1 -0
- package/lib/module/core/authMachine.js +402 -0
- package/lib/module/core/authMachine.js.map +1 -0
- package/lib/module/core/profile.js +54 -0
- package/lib/module/core/profile.js.map +1 -0
- package/lib/module/core/session.js +118 -0
- package/lib/module/core/session.js.map +1 -0
- package/lib/module/diagnostics/errors.js +74 -0
- package/lib/module/diagnostics/errors.js.map +1 -0
- package/lib/module/diagnostics/messageKeys.js +46 -0
- package/lib/module/diagnostics/messageKeys.js.map +1 -0
- package/lib/module/index.js +33 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/keychain.js +9 -0
- package/lib/module/keychain.js.map +1 -0
- package/lib/module/oidc/authClient.js +152 -0
- package/lib/module/oidc/authClient.js.map +1 -0
- package/lib/module/oidc/classifyError.js +60 -0
- package/lib/module/oidc/classifyError.js.map +1 -0
- package/lib/module/oidc/socialRouting.js +52 -0
- package/lib/module/oidc/socialRouting.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/react/AuthProvider.js +31 -0
- package/lib/module/react/AuthProvider.js.map +1 -0
- package/lib/module/react/hooks.js +111 -0
- package/lib/module/react/hooks.js.map +1 -0
- package/lib/module/testing/conformance.js +140 -0
- package/lib/module/testing/conformance.js.map +1 -0
- package/lib/module/testing/index.js +25 -0
- package/lib/module/testing/index.js.map +1 -0
- package/lib/module/tokens/accessToken.js +161 -0
- package/lib/module/tokens/accessToken.js.map +1 -0
- package/lib/module/tokens/secureStore.js +56 -0
- package/lib/module/tokens/secureStore.js.map +1 -0
- package/lib/typescript/commonjs/access/accessTier.d.ts +14 -0
- package/lib/typescript/commonjs/access/accessTier.d.ts.map +1 -0
- package/lib/typescript/commonjs/app-auth.d.ts +7 -0
- package/lib/typescript/commonjs/app-auth.d.ts.map +1 -0
- package/lib/typescript/commonjs/config/types.d.ts +171 -0
- package/lib/typescript/commonjs/config/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/config/validateConfig.d.ts +8 -0
- package/lib/typescript/commonjs/config/validateConfig.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/authMachine.d.ts +14 -0
- package/lib/typescript/commonjs/core/authMachine.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/profile.d.ts +15 -0
- package/lib/typescript/commonjs/core/profile.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/session.d.ts +60 -0
- package/lib/typescript/commonjs/core/session.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts +37 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts +57 -0
- package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +27 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/keychain.d.ts +7 -0
- package/lib/typescript/commonjs/keychain.d.ts.map +1 -0
- package/lib/typescript/commonjs/oidc/authClient.d.ts +75 -0
- package/lib/typescript/commonjs/oidc/authClient.d.ts.map +1 -0
- package/lib/typescript/commonjs/oidc/classifyError.d.ts +28 -0
- package/lib/typescript/commonjs/oidc/classifyError.d.ts.map +1 -0
- package/lib/typescript/commonjs/oidc/socialRouting.d.ts +22 -0
- package/lib/typescript/commonjs/oidc/socialRouting.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/react/AuthProvider.d.ts +17 -0
- package/lib/typescript/commonjs/react/AuthProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/react/hooks.d.ts +42 -0
- package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
- package/lib/typescript/commonjs/testing/conformance.d.ts +32 -0
- package/lib/typescript/commonjs/testing/conformance.d.ts.map +1 -0
- package/lib/typescript/commonjs/testing/index.d.ts +11 -0
- package/lib/typescript/commonjs/testing/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/tokens/accessToken.d.ts +45 -0
- package/lib/typescript/commonjs/tokens/accessToken.d.ts.map +1 -0
- package/lib/typescript/commonjs/tokens/secureStore.d.ts +26 -0
- package/lib/typescript/commonjs/tokens/secureStore.d.ts.map +1 -0
- package/lib/typescript/module/access/accessTier.d.ts +14 -0
- package/lib/typescript/module/access/accessTier.d.ts.map +1 -0
- package/lib/typescript/module/app-auth.d.ts +7 -0
- package/lib/typescript/module/app-auth.d.ts.map +1 -0
- package/lib/typescript/module/config/types.d.ts +171 -0
- package/lib/typescript/module/config/types.d.ts.map +1 -0
- package/lib/typescript/module/config/validateConfig.d.ts +8 -0
- package/lib/typescript/module/config/validateConfig.d.ts.map +1 -0
- package/lib/typescript/module/core/authMachine.d.ts +14 -0
- package/lib/typescript/module/core/authMachine.d.ts.map +1 -0
- package/lib/typescript/module/core/profile.d.ts +15 -0
- package/lib/typescript/module/core/profile.d.ts.map +1 -0
- package/lib/typescript/module/core/session.d.ts +60 -0
- package/lib/typescript/module/core/session.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/errors.d.ts +37 -0
- package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/messageKeys.d.ts +57 -0
- package/lib/typescript/module/diagnostics/messageKeys.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +27 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/keychain.d.ts +7 -0
- package/lib/typescript/module/keychain.d.ts.map +1 -0
- package/lib/typescript/module/oidc/authClient.d.ts +75 -0
- package/lib/typescript/module/oidc/authClient.d.ts.map +1 -0
- package/lib/typescript/module/oidc/classifyError.d.ts +28 -0
- package/lib/typescript/module/oidc/classifyError.d.ts.map +1 -0
- package/lib/typescript/module/oidc/socialRouting.d.ts +22 -0
- package/lib/typescript/module/oidc/socialRouting.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/react/AuthProvider.d.ts +17 -0
- package/lib/typescript/module/react/AuthProvider.d.ts.map +1 -0
- package/lib/typescript/module/react/hooks.d.ts +42 -0
- package/lib/typescript/module/react/hooks.d.ts.map +1 -0
- package/lib/typescript/module/testing/conformance.d.ts +32 -0
- package/lib/typescript/module/testing/conformance.d.ts.map +1 -0
- package/lib/typescript/module/testing/index.d.ts +11 -0
- package/lib/typescript/module/testing/index.d.ts.map +1 -0
- package/lib/typescript/module/tokens/accessToken.d.ts +45 -0
- package/lib/typescript/module/tokens/accessToken.d.ts.map +1 -0
- package/lib/typescript/module/tokens/secureStore.d.ts +26 -0
- package/lib/typescript/module/tokens/secureStore.d.ts.map +1 -0
- package/package.json +68 -21
- package/skills/sdk-rn-auth/SKILL.md +35 -2
- package/src/config/types.ts +53 -5
- package/src/config/validateConfig.ts +32 -1
- package/src/core/authMachine.ts +40 -6
- package/src/core/profile.ts +6 -1
- package/src/core/session.ts +49 -3
- package/src/diagnostics/errors.ts +7 -5
- package/src/index.ts +7 -0
- package/src/oidc/authClient.ts +19 -1
- package/src/oidc/classifyError.ts +2 -1
- package/src/oidc/socialRouting.ts +3 -1
- package/src/react/hooks.ts +53 -14
- package/src/tokens/accessToken.ts +20 -9
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Access-tier evaluation (FR-010/FR-011/FR-019/FR-020, R6).
|
|
5
|
+
*
|
|
6
|
+
* Pure function over the authenticated token's claims and the app-specific
|
|
7
|
+
* mapping. Object ids are authoritative; display names never grant access.
|
|
8
|
+
* Missing, stale, ambiguous, or group-overage claims fail closed (premium
|
|
9
|
+
* denied, verification = 'unverified').
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** The fail-closed default: free + unverified. */
|
|
13
|
+
export function failClosedTier() {
|
|
14
|
+
return {
|
|
15
|
+
tier: 'free',
|
|
16
|
+
source: 'default',
|
|
17
|
+
verification: 'unverified'
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function toStringArray(value) {
|
|
21
|
+
if (Array.isArray(value)) {
|
|
22
|
+
return value.filter(entry => typeof entry === 'string');
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === 'string') {
|
|
25
|
+
return [value];
|
|
26
|
+
}
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Entra emits a groups overage indicator (`_claim_names.groups` or `hasgroups`)
|
|
32
|
+
* instead of inline groups when the list is too large. Reading the full list
|
|
33
|
+
* would require Graph (out of scope, FR-012), so overage fails closed.
|
|
34
|
+
*/
|
|
35
|
+
function hasGroupOverage(claims) {
|
|
36
|
+
if (claims.hasgroups === true) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
const claimNames = claims._claim_names;
|
|
40
|
+
if (claimNames && typeof claimNames === 'object' && 'groups' in claimNames) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
function matchesClaim(claims, matcher) {
|
|
46
|
+
const value = claims[matcher.claim];
|
|
47
|
+
if (Array.isArray(value)) {
|
|
48
|
+
return value.includes(matcher.equals);
|
|
49
|
+
}
|
|
50
|
+
return value === matcher.equals;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Evaluate the access tier, failing closed when entitlement is unverifiable. */
|
|
54
|
+
export function evaluateAccessTier(claims, mapping, now = Date.now()) {
|
|
55
|
+
// Object ids first (authoritative). Display names are never consulted.
|
|
56
|
+
const groups = toStringArray(claims.groups);
|
|
57
|
+
if (mapping.premiumGroupObjectIds.length > 0 && groups.some(group => mapping.premiumGroupObjectIds.includes(group))) {
|
|
58
|
+
return {
|
|
59
|
+
tier: 'premium',
|
|
60
|
+
source: 'group',
|
|
61
|
+
verification: 'verified',
|
|
62
|
+
lastRefreshAt: now
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Roles next.
|
|
67
|
+
const roles = toStringArray(claims.roles);
|
|
68
|
+
if (mapping.premiumRoleNames?.length && roles.some(role => mapping.premiumRoleNames.includes(role))) {
|
|
69
|
+
return {
|
|
70
|
+
tier: 'premium',
|
|
71
|
+
source: 'role',
|
|
72
|
+
verification: 'verified',
|
|
73
|
+
lastRefreshAt: now
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Custom claim matchers last.
|
|
78
|
+
if (mapping.premiumClaimMatchers?.some(matcher => matchesClaim(claims, matcher))) {
|
|
79
|
+
return {
|
|
80
|
+
tier: 'premium',
|
|
81
|
+
source: 'claim',
|
|
82
|
+
verification: 'verified',
|
|
83
|
+
lastRefreshAt: now
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// No premium indicator matched. If group claims are unavailable due to
|
|
88
|
+
// overage and premium depends on groups, we cannot verify → fail closed.
|
|
89
|
+
if (mapping.premiumGroupObjectIds.length > 0 && hasGroupOverage(claims)) {
|
|
90
|
+
return {
|
|
91
|
+
tier: 'free',
|
|
92
|
+
source: 'default',
|
|
93
|
+
verification: 'unverified',
|
|
94
|
+
lastRefreshAt: now
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Verified free: claims were present and simply did not grant premium.
|
|
99
|
+
return {
|
|
100
|
+
tier: 'free',
|
|
101
|
+
source: 'default',
|
|
102
|
+
verification: 'verified',
|
|
103
|
+
lastRefreshAt: now
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=accessTier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["failClosedTier","tier","source","verification","toStringArray","value","Array","isArray","filter","entry","hasGroupOverage","claims","hasgroups","claimNames","_claim_names","matchesClaim","matcher","claim","includes","equals","evaluateAccessTier","mapping","now","Date","groups","premiumGroupObjectIds","length","some","group","lastRefreshAt","roles","premiumRoleNames","role","premiumClaimMatchers"],"sourceRoot":"../../../src","sources":["access/accessTier.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `@chipmobilesdk/rn-auth/app-auth`: the default OIDC client over
|
|
5
|
+
* react-native-app-auth (AUTH-09). Its own entrypoint, so an app that injects its
|
|
6
|
+
* own client never reaches this module.
|
|
7
|
+
*/
|
|
8
|
+
export { createAppAuthClient } from "./oidc/authClient.js";
|
|
9
|
+
//# sourceMappingURL=app-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createAppAuthClient"],"sourceRoot":"../../src","sources":["app-auth.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA,SAASA,mBAAmB,QAAmC,sBAAmB","ignoreList":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Public type contracts for @chipmobilesdk/rn-auth. Shapes follow
|
|
5
|
+
* specs/003-mobile-entra-auth/data-model.md.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** The providers this package has copy for out of the box. */
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A provider id. Open on purpose: routing is `domain_hint` and nothing else, so
|
|
12
|
+
* adding an IdP the tenant federates — Microsoft account, an email one-time
|
|
13
|
+
* code — is a change to an app's config, not a release of this package
|
|
14
|
+
* (AUTH-14). `KnownProviderId` keeps the three familiar ones in autocomplete.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const DEVICE_PLATFORMS = ['ios', 'android'];
|
|
18
|
+
|
|
19
|
+
/** Provider Setup Configuration — non-secret public values only (FR-016/FR-017). */
|
|
20
|
+
|
|
21
|
+
/** One configured protected resource for delegated token requests (FR-007). */
|
|
22
|
+
|
|
23
|
+
/** App-specific mapping from tenant indicators to access tiers (FR-019/FR-020). */
|
|
24
|
+
|
|
25
|
+
/** App-supplied, public-only setup input (FR-015/FR-016/FR-017). */
|
|
26
|
+
|
|
27
|
+
/** Advanced/testing options. `platform` overrides the detected device platform. */
|
|
28
|
+
|
|
29
|
+
/** Customer User / app-visible profile (FR-006). */
|
|
30
|
+
|
|
31
|
+
/** Access Tier — local interpretation of tenant indicators (FR-010). */
|
|
32
|
+
|
|
33
|
+
/** Access Token Request result (FR-007). */
|
|
34
|
+
|
|
35
|
+
/** Single active app-visible authenticated state (FR-005/FR-022). */
|
|
36
|
+
|
|
37
|
+
/** Result of a premium-only gate check (US3). */
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* What `signOutGlobal` did beyond the device (added in 0.2.2). Local state is
|
|
41
|
+
* cleared either way; `failed` means the tenant session may still be alive, so
|
|
42
|
+
* the next interactive sign-in can complete without a password prompt.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/** The auth controller returned by `createAuth` (single active account). */
|
|
46
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DEVICE_PLATFORMS"],"sourceRoot":"../../../src","sources":["config/types.ts"],"mappings":";;AAAA;AACA;AACA;AACA;;AAQA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAIA,OAAO,MAAMA,gBAA2C,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC;;AAE7E;;AAoBA;;AAYA;;AAUA;;AAmBA;;AAiBA;;AAoBA;;AAUA;;AASA;;AASA;;AAMA;AACA;AACA;AACA;AACA;;AAOA","ignoreList":[]}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deterministic configuration validation (FR-005 → configuration-error).
|
|
5
|
+
* Throws AuthConfigError before any provider flow can start (US4 scenario 2).
|
|
6
|
+
* Covers the auth-config.md Section A–F rules.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { DEVICE_PLATFORMS } from "./types.js";
|
|
10
|
+
import { AuthConfigError } from "../diagnostics/errors.js";
|
|
11
|
+
function hasScheme(url) {
|
|
12
|
+
return /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(url);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** https, or http on a development machine. */
|
|
16
|
+
function isSecureAuthority(url) {
|
|
17
|
+
if (/^https:/i.test(url)) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
return /^http:\/\/(localhost|127\.0\.0\.1|\[::1\])(:\d+)?(\/|$)/i.test(url);
|
|
21
|
+
}
|
|
22
|
+
export function validateConfig(config) {
|
|
23
|
+
// Section A — tenant/client settings
|
|
24
|
+
if (!config.authority || !config.authority.trim()) {
|
|
25
|
+
throw new AuthConfigError('auth.error.configuration', 'Missing "authority"');
|
|
26
|
+
}
|
|
27
|
+
if (!hasScheme(config.authority)) {
|
|
28
|
+
throw new AuthConfigError('auth.error.configuration', '"authority" must be an absolute URL');
|
|
29
|
+
}
|
|
30
|
+
// Tokens travel over this. A tenant reachable over plaintext http is a
|
|
31
|
+
// configuration mistake, not a deployment choice — except on a dev machine.
|
|
32
|
+
if (!isSecureAuthority(config.authority)) {
|
|
33
|
+
throw new AuthConfigError('auth.error.configuration', '"authority" must use https (http is accepted only for localhost)');
|
|
34
|
+
}
|
|
35
|
+
if (!config.clientId || !config.clientId.trim()) {
|
|
36
|
+
throw new AuthConfigError('auth.error.configuration', 'Missing "clientId"');
|
|
37
|
+
}
|
|
38
|
+
if (!config.redirectUrl || !config.redirectUrl.trim()) {
|
|
39
|
+
throw new AuthConfigError('auth.error.configuration', 'Missing "redirectUrl"');
|
|
40
|
+
}
|
|
41
|
+
if (!hasScheme(config.redirectUrl)) {
|
|
42
|
+
throw new AuthConfigError('auth.error.redirectMismatch', '"redirectUrl" must include a scheme matching the native redirect configuration');
|
|
43
|
+
}
|
|
44
|
+
if (!Array.isArray(config.scopes) || config.scopes.length === 0) {
|
|
45
|
+
throw new AuthConfigError('auth.error.configuration', 'At least one OIDC scope is required');
|
|
46
|
+
}
|
|
47
|
+
if (!config.scopes.includes('offline_access')) {
|
|
48
|
+
throw new AuthConfigError('auth.error.configuration', '"offline_access" scope is required for session restore and silent refresh');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Sections B/C — providers
|
|
52
|
+
if (!Array.isArray(config.providers) || config.providers.length === 0) {
|
|
53
|
+
throw new AuthConfigError('auth.error.configuration', 'At least one provider must be configured');
|
|
54
|
+
}
|
|
55
|
+
const providerIds = new Set();
|
|
56
|
+
for (const provider of config.providers) {
|
|
57
|
+
if (providerIds.has(provider.id)) {
|
|
58
|
+
throw new AuthConfigError('auth.error.configuration', `Duplicate provider "${provider.id}"`);
|
|
59
|
+
}
|
|
60
|
+
providerIds.add(provider.id);
|
|
61
|
+
if (!provider.domainHint || !provider.domainHint.trim()) {
|
|
62
|
+
throw new AuthConfigError('auth.error.configuration', `Provider "${provider.id}" is missing a domainHint`);
|
|
63
|
+
}
|
|
64
|
+
if (!Array.isArray(provider.platforms) || provider.platforms.length === 0) {
|
|
65
|
+
throw new AuthConfigError('auth.error.configuration', `Provider "${provider.id}" must declare at least one platform`);
|
|
66
|
+
}
|
|
67
|
+
for (const platform of provider.platforms) {
|
|
68
|
+
if (!DEVICE_PLATFORMS.includes(platform)) {
|
|
69
|
+
// A typo here hides the provider on every device rather than failing.
|
|
70
|
+
throw new AuthConfigError('auth.error.configuration', `Provider "${provider.id}" declares unknown platform "${String(platform)}"`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (typeof provider.labelKey !== 'string' || !provider.labelKey.trim()) {
|
|
74
|
+
throw new AuthConfigError('auth.error.configuration', `Provider "${provider.id}" is missing a labelKey`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Section D — resources
|
|
79
|
+
if (config.resources) {
|
|
80
|
+
const resourceKeys = new Set();
|
|
81
|
+
for (const resource of config.resources) {
|
|
82
|
+
if (!resource.key || !resource.key.trim()) {
|
|
83
|
+
throw new AuthConfigError('auth.error.configuration', 'A resource is missing "key"');
|
|
84
|
+
}
|
|
85
|
+
if (resourceKeys.has(resource.key)) {
|
|
86
|
+
throw new AuthConfigError('auth.error.configuration', `Duplicate resource "${resource.key}"`);
|
|
87
|
+
}
|
|
88
|
+
resourceKeys.add(resource.key);
|
|
89
|
+
if (!Array.isArray(resource.scopes) || resource.scopes.length === 0) {
|
|
90
|
+
throw new AuthConfigError('auth.error.configuration', `Resource "${resource.key}" must declare at least one scope`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Section E — access-tier mapping
|
|
96
|
+
const mapping = config.accessTierMapping;
|
|
97
|
+
if (!mapping) {
|
|
98
|
+
throw new AuthConfigError('auth.error.configuration', 'Missing "accessTierMapping"');
|
|
99
|
+
}
|
|
100
|
+
const hasPremiumIndicator = (mapping.premiumGroupObjectIds?.length ?? 0) > 0 || (mapping.premiumRoleNames?.length ?? 0) > 0 || (mapping.premiumClaimMatchers?.length ?? 0) > 0;
|
|
101
|
+
if (!hasPremiumIndicator) {
|
|
102
|
+
throw new AuthConfigError('auth.error.configuration', 'accessTierMapping must define at least one premium group object id, role name, or claim matcher');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Section F — injected ports
|
|
106
|
+
if (!config.secureStore) {
|
|
107
|
+
throw new AuthConfigError('auth.error.configuration', 'A secureStore is required (FR-021)');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=validateConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DEVICE_PLATFORMS","AuthConfigError","hasScheme","url","test","isSecureAuthority","validateConfig","config","authority","trim","clientId","redirectUrl","Array","isArray","scopes","length","includes","providers","providerIds","Set","provider","has","id","add","domainHint","platforms","platform","String","labelKey","resources","resourceKeys","resource","key","mapping","accessTierMapping","hasPremiumIndicator","premiumGroupObjectIds","premiumRoleNames","premiumClaimMatchers","secureStore"],"sourceRoot":"../../../src","sources":["config/validateConfig.ts"],"mappings":"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","ignoreList":[]}
|