@masterteam/gateway-auth 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.
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
const GATEWAY_AUTH_DEVICE_TOKEN = 'web-app';
|
|
2
|
+
const GATEWAY_AUTH_ENDPOINTS = {
|
|
3
|
+
login: 'auth/login',
|
|
4
|
+
verifyMfa: 'auth/2fa/verify',
|
|
5
|
+
resendMfa: 'auth/2fa/resend',
|
|
6
|
+
refresh: 'auth/refresh',
|
|
7
|
+
logout: 'auth/logout',
|
|
8
|
+
ssoProviders: 'auth/sso/providers',
|
|
9
|
+
ssoExchange: 'auth/sso/exchange',
|
|
10
|
+
ssoTokenExchange: 'auth/sso/token-exchange',
|
|
11
|
+
nafathStart: (providerKey) => `auth/sso/nafath/${encodeURIComponent(providerKey)}/start`,
|
|
12
|
+
nafathStatus: (providerKey) => `auth/sso/nafath/${encodeURIComponent(providerKey)}/status`,
|
|
13
|
+
ssoStart: (providerKey) => `auth/sso/${encodeURIComponent(providerKey)}/start`,
|
|
14
|
+
};
|
|
15
|
+
function isExpired(expireAt) {
|
|
16
|
+
if (!expireAt) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const timestamp = new Date(expireAt).getTime();
|
|
20
|
+
return !Number.isFinite(timestamp) || timestamp <= Date.now();
|
|
21
|
+
}
|
|
22
|
+
function resolveApiDateValue(value) {
|
|
23
|
+
return value?.actualValue ?? value?.rawValue ?? null;
|
|
24
|
+
}
|
|
25
|
+
function mapGatewayTokens(tokens) {
|
|
26
|
+
return {
|
|
27
|
+
accessToken: tokens.accessToken,
|
|
28
|
+
refreshToken: tokens.refreshToken,
|
|
29
|
+
accessTokenExpiresAt: resolveApiDateValue(tokens.accessTokenExpiresAt),
|
|
30
|
+
refreshTokenExpiresAt: resolveApiDateValue(tokens.refreshTokenExpiresAt),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function mapGatewayUser(user, tokenData, delegations) {
|
|
34
|
+
const photo = typeof user.photo === 'string' ? { fileName: user.photo } : user.photo;
|
|
35
|
+
const imageFallback = user.image ? { fileName: user.image } : undefined;
|
|
36
|
+
const resolvedPhoto = photo ?? imageFallback;
|
|
37
|
+
return {
|
|
38
|
+
user: {
|
|
39
|
+
...user,
|
|
40
|
+
photo: resolvedPhoto,
|
|
41
|
+
},
|
|
42
|
+
token: tokenData.accessToken,
|
|
43
|
+
accessToken: tokenData.accessToken,
|
|
44
|
+
refreshToken: tokenData.refreshToken,
|
|
45
|
+
accessTokenExpiresAt: tokenData.accessTokenExpiresAt ?? undefined,
|
|
46
|
+
refreshTokenExpiresAt: tokenData.refreshTokenExpiresAt ?? undefined,
|
|
47
|
+
delegations: delegations ?? [],
|
|
48
|
+
twoFactorRequired: false,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function hasGatewayTokens(tokens) {
|
|
52
|
+
return Boolean(tokens?.accessToken && tokens?.refreshToken);
|
|
53
|
+
}
|
|
54
|
+
function getGatewayErrorMessage(error, fallback) {
|
|
55
|
+
const response = error;
|
|
56
|
+
return (response.error?.message ??
|
|
57
|
+
response.error?.Message ??
|
|
58
|
+
response.error?.errors?.message ??
|
|
59
|
+
response.message ??
|
|
60
|
+
fallback);
|
|
61
|
+
}
|
|
62
|
+
function normalizeGatewayBase(baseUrl) {
|
|
63
|
+
if (!baseUrl) {
|
|
64
|
+
return '';
|
|
65
|
+
}
|
|
66
|
+
return baseUrl.replace(/\/+$/, '');
|
|
67
|
+
}
|
|
68
|
+
function buildGatewayUrl(gatewayApiBaseUrl, path) {
|
|
69
|
+
if (/^https?:\/\//i.test(path)) {
|
|
70
|
+
return path;
|
|
71
|
+
}
|
|
72
|
+
const normalizedBase = normalizeGatewayBase(gatewayApiBaseUrl);
|
|
73
|
+
if (!normalizedBase) {
|
|
74
|
+
return path;
|
|
75
|
+
}
|
|
76
|
+
const normalizedPath = path.replace(/^\/+/, '');
|
|
77
|
+
if (normalizedPath.startsWith('api/')) {
|
|
78
|
+
try {
|
|
79
|
+
const base = new URL(normalizedBase);
|
|
80
|
+
return `${base.origin}/${normalizedPath}`;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return `${normalizedBase}/${normalizedPath}`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return `${normalizedBase}/${normalizedPath}`;
|
|
87
|
+
}
|
|
88
|
+
function buildSsoStartUrl({ gatewayApiBaseUrl, provider, returnUrl, clientState, platform = 'web', }) {
|
|
89
|
+
const startPath = provider.startUrl || GATEWAY_AUTH_ENDPOINTS.ssoStart(provider.key);
|
|
90
|
+
const url = new URL(buildGatewayUrl(gatewayApiBaseUrl, startPath));
|
|
91
|
+
url.searchParams.set('platform', platform);
|
|
92
|
+
url.searchParams.set('returnUrl', returnUrl);
|
|
93
|
+
url.searchParams.set('clientState', clientState);
|
|
94
|
+
return url.toString();
|
|
95
|
+
}
|
|
96
|
+
function createSecureClientState() {
|
|
97
|
+
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
|
98
|
+
return crypto.randomUUID();
|
|
99
|
+
}
|
|
100
|
+
const bytes = new Uint8Array(16);
|
|
101
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
102
|
+
crypto.getRandomValues(bytes);
|
|
103
|
+
return Array.from(bytes, (value) => value.toString(16).padStart(2, '0')).join('');
|
|
104
|
+
}
|
|
105
|
+
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const PENDING_SSO_STATE_KEY = 'gatewayAuth.pendingSsoState';
|
|
109
|
+
class GatewaySsoSession {
|
|
110
|
+
createAndStoreState() {
|
|
111
|
+
const state = createSecureClientState();
|
|
112
|
+
this.storage?.setItem(PENDING_SSO_STATE_KEY, state);
|
|
113
|
+
return state;
|
|
114
|
+
}
|
|
115
|
+
getPendingState() {
|
|
116
|
+
return this.storage?.getItem(PENDING_SSO_STATE_KEY) ?? null;
|
|
117
|
+
}
|
|
118
|
+
clearPendingState() {
|
|
119
|
+
this.storage?.removeItem(PENDING_SSO_STATE_KEY);
|
|
120
|
+
}
|
|
121
|
+
consumeExpectedState(state) {
|
|
122
|
+
const expectedState = this.getPendingState();
|
|
123
|
+
this.clearPendingState();
|
|
124
|
+
return Boolean(state && expectedState && state === expectedState);
|
|
125
|
+
}
|
|
126
|
+
clearCallbackQuery(path = '/auth/sso/callback') {
|
|
127
|
+
if (typeof window === 'undefined' || !window.history?.replaceState) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
window.history.replaceState({}, document.title, path);
|
|
131
|
+
}
|
|
132
|
+
clearAll() {
|
|
133
|
+
this.clearPendingState();
|
|
134
|
+
}
|
|
135
|
+
get storage() {
|
|
136
|
+
if (typeof sessionStorage === 'undefined') {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
return sessionStorage;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Generated bundle index. Do not edit.
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
export { GATEWAY_AUTH_DEVICE_TOKEN, GATEWAY_AUTH_ENDPOINTS, GatewaySsoSession, buildGatewayUrl, buildSsoStartUrl, createSecureClientState, getGatewayErrorMessage, hasGatewayTokens, isExpired, mapGatewayTokens, mapGatewayUser, normalizeGatewayBase, resolveApiDateValue };
|
|
148
|
+
//# sourceMappingURL=masterteam-gateway-auth.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masterteam-gateway-auth.mjs","sources":["../../../../packages/masterteam/gateway-auth/src/gateway-auth.utils.ts","../../../../packages/masterteam/gateway-auth/src/gateway-sso-session.service.ts","../../../../packages/masterteam/gateway-auth/src/masterteam-gateway-auth.ts"],"sourcesContent":["import {\n GatewayApiDateValue,\n GatewayAuthTokens,\n GatewayMappedTokens,\n GatewayMappedUser,\n GatewayRefreshData,\n GatewaySsoProvider,\n GatewayUserDetails,\n} from './gateway-auth.models';\n\nexport const GATEWAY_AUTH_DEVICE_TOKEN = 'web-app';\n\nexport const GATEWAY_AUTH_ENDPOINTS = {\n login: 'auth/login',\n verifyMfa: 'auth/2fa/verify',\n resendMfa: 'auth/2fa/resend',\n refresh: 'auth/refresh',\n logout: 'auth/logout',\n ssoProviders: 'auth/sso/providers',\n ssoExchange: 'auth/sso/exchange',\n ssoTokenExchange: 'auth/sso/token-exchange',\n nafathStart: (providerKey: string) =>\n `auth/sso/nafath/${encodeURIComponent(providerKey)}/start`,\n nafathStatus: (providerKey: string) =>\n `auth/sso/nafath/${encodeURIComponent(providerKey)}/status`,\n ssoStart: (providerKey: string) =>\n `auth/sso/${encodeURIComponent(providerKey)}/start`,\n} as const;\n\nexport function isExpired(expireAt?: string | null): boolean {\n if (!expireAt) {\n return false;\n }\n\n const timestamp = new Date(expireAt).getTime();\n return !Number.isFinite(timestamp) || timestamp <= Date.now();\n}\n\nexport function resolveApiDateValue(\n value?: GatewayApiDateValue | null,\n): string | null {\n return value?.actualValue ?? value?.rawValue ?? null;\n}\n\nexport function mapGatewayTokens(\n tokens: GatewayAuthTokens | GatewayRefreshData,\n): GatewayMappedTokens {\n return {\n accessToken: tokens.accessToken,\n refreshToken: tokens.refreshToken,\n accessTokenExpiresAt: resolveApiDateValue(tokens.accessTokenExpiresAt),\n refreshTokenExpiresAt: resolveApiDateValue(tokens.refreshTokenExpiresAt),\n };\n}\n\nexport function mapGatewayUser(\n user: GatewayUserDetails,\n tokenData: GatewayMappedTokens,\n delegations?: unknown[],\n): GatewayMappedUser {\n const photo =\n typeof user.photo === 'string' ? { fileName: user.photo } : user.photo;\n const imageFallback = user.image ? { fileName: user.image } : undefined;\n const resolvedPhoto = photo ?? imageFallback;\n\n return {\n user: {\n ...user,\n photo: resolvedPhoto,\n },\n token: tokenData.accessToken,\n accessToken: tokenData.accessToken,\n refreshToken: tokenData.refreshToken,\n accessTokenExpiresAt: tokenData.accessTokenExpiresAt ?? undefined,\n refreshTokenExpiresAt: tokenData.refreshTokenExpiresAt ?? undefined,\n delegations: delegations ?? [],\n twoFactorRequired: false,\n };\n}\n\nexport function hasGatewayTokens(\n tokens?: Partial<GatewayAuthTokens | GatewayRefreshData> | null,\n): boolean {\n return Boolean(tokens?.accessToken && tokens?.refreshToken);\n}\n\nexport function getGatewayErrorMessage(\n error: unknown,\n fallback: string,\n): string {\n const response = error as {\n error?: { message?: string; Message?: string; errors?: { message?: string } };\n message?: string;\n };\n\n return (\n response.error?.message ??\n response.error?.Message ??\n response.error?.errors?.message ??\n response.message ??\n fallback\n );\n}\n\nexport function normalizeGatewayBase(baseUrl?: string | null): string {\n if (!baseUrl) {\n return '';\n }\n\n return baseUrl.replace(/\\/+$/, '');\n}\n\nexport function buildGatewayUrl(\n gatewayApiBaseUrl: string | undefined | null,\n path: string,\n): string {\n if (/^https?:\\/\\//i.test(path)) {\n return path;\n }\n\n const normalizedBase = normalizeGatewayBase(gatewayApiBaseUrl);\n if (!normalizedBase) {\n return path;\n }\n\n const normalizedPath = path.replace(/^\\/+/, '');\n if (normalizedPath.startsWith('api/')) {\n try {\n const base = new URL(normalizedBase);\n return `${base.origin}/${normalizedPath}`;\n } catch {\n return `${normalizedBase}/${normalizedPath}`;\n }\n }\n\n return `${normalizedBase}/${normalizedPath}`;\n}\n\nexport interface BuildSsoStartUrlOptions {\n gatewayApiBaseUrl: string;\n provider: GatewaySsoProvider;\n returnUrl: string;\n clientState: string;\n platform?: 'web' | 'mobile';\n}\n\nexport function buildSsoStartUrl({\n gatewayApiBaseUrl,\n provider,\n returnUrl,\n clientState,\n platform = 'web',\n}: BuildSsoStartUrlOptions): string {\n const startPath = provider.startUrl || GATEWAY_AUTH_ENDPOINTS.ssoStart(provider.key);\n const url = new URL(buildGatewayUrl(gatewayApiBaseUrl, startPath));\n url.searchParams.set('platform', platform);\n url.searchParams.set('returnUrl', returnUrl);\n url.searchParams.set('clientState', clientState);\n return url.toString();\n}\n\nexport function createSecureClientState(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n\n const bytes = new Uint8Array(16);\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (value) => value.toString(16).padStart(2, '0')).join(\n '',\n );\n }\n\n return `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;\n}\n\n","import { createSecureClientState } from './gateway-auth.utils';\n\nconst PENDING_SSO_STATE_KEY = 'gatewayAuth.pendingSsoState';\n\nexport class GatewaySsoSession {\n createAndStoreState(): string {\n const state = createSecureClientState();\n this.storage?.setItem(PENDING_SSO_STATE_KEY, state);\n return state;\n }\n\n getPendingState(): string | null {\n return this.storage?.getItem(PENDING_SSO_STATE_KEY) ?? null;\n }\n\n clearPendingState(): void {\n this.storage?.removeItem(PENDING_SSO_STATE_KEY);\n }\n\n consumeExpectedState(state: string | null): boolean {\n const expectedState = this.getPendingState();\n this.clearPendingState();\n return Boolean(state && expectedState && state === expectedState);\n }\n\n clearCallbackQuery(path = '/auth/sso/callback'): void {\n if (typeof window === 'undefined' || !window.history?.replaceState) {\n return;\n }\n\n window.history.replaceState({}, document.title, path);\n }\n\n clearAll(): void {\n this.clearPendingState();\n }\n\n private get storage(): Storage | null {\n if (typeof sessionStorage === 'undefined') {\n return null;\n }\n\n return sessionStorage;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@masterteam/gateway-auth",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"directory": "../../../dist/masterteam/gateway-auth",
|
|
6
|
+
"linkDirectory": true,
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"peerDependencies": {},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/MasterteamSA/components.git"
|
|
13
|
+
},
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"module": "fesm2022/masterteam-gateway-auth.mjs",
|
|
16
|
+
"typings": "types/masterteam-gateway-auth.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
"./package.json": {
|
|
19
|
+
"default": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./types/masterteam-gateway-auth.d.ts",
|
|
23
|
+
"default": "./fesm2022/masterteam-gateway-auth.mjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"tslib": "^2.8.1"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
interface GatewayResponse<T> {
|
|
2
|
+
endpoint: string;
|
|
3
|
+
status: number;
|
|
4
|
+
code: number;
|
|
5
|
+
locale: string;
|
|
6
|
+
message?: string | null;
|
|
7
|
+
errors?: unknown | null;
|
|
8
|
+
data: T;
|
|
9
|
+
cacheSession?: string;
|
|
10
|
+
}
|
|
11
|
+
interface GatewayApiDateValue {
|
|
12
|
+
displayValue?: string;
|
|
13
|
+
actualValue?: string;
|
|
14
|
+
rawValue?: string;
|
|
15
|
+
}
|
|
16
|
+
interface GatewayUserDetails {
|
|
17
|
+
id: string;
|
|
18
|
+
userName?: string;
|
|
19
|
+
displayName?: string;
|
|
20
|
+
email?: string;
|
|
21
|
+
mobile?: string;
|
|
22
|
+
ext?: string;
|
|
23
|
+
isExternal?: boolean;
|
|
24
|
+
passwordChangeRequired?: boolean;
|
|
25
|
+
image?: string;
|
|
26
|
+
photo?: {
|
|
27
|
+
fileName?: string;
|
|
28
|
+
} | string;
|
|
29
|
+
extraInfo?: Array<{
|
|
30
|
+
key: string;
|
|
31
|
+
value: string;
|
|
32
|
+
}>;
|
|
33
|
+
providerExtraInfo?: Array<{
|
|
34
|
+
key: string;
|
|
35
|
+
value: string;
|
|
36
|
+
}>;
|
|
37
|
+
stars?: number;
|
|
38
|
+
createdAt?: GatewayApiDateValue;
|
|
39
|
+
lastLoginTime?: GatewayApiDateValue;
|
|
40
|
+
department?: string;
|
|
41
|
+
cn?: string;
|
|
42
|
+
name?: string;
|
|
43
|
+
groups?: unknown;
|
|
44
|
+
roles?: unknown;
|
|
45
|
+
}
|
|
46
|
+
interface GatewayAuthTokens {
|
|
47
|
+
accessToken: string;
|
|
48
|
+
accessTokenExpiresAt: GatewayApiDateValue;
|
|
49
|
+
refreshToken: string;
|
|
50
|
+
refreshTokenExpiresAt: GatewayApiDateValue;
|
|
51
|
+
}
|
|
52
|
+
interface GatewayRefreshData {
|
|
53
|
+
accessToken: string;
|
|
54
|
+
accessTokenExpiresAt: GatewayApiDateValue;
|
|
55
|
+
refreshToken: string;
|
|
56
|
+
refreshTokenExpiresAt: GatewayApiDateValue;
|
|
57
|
+
}
|
|
58
|
+
interface GatewayTwoFactorChallenge {
|
|
59
|
+
userId: string;
|
|
60
|
+
tempSessionId: string;
|
|
61
|
+
expiresAtUtc: string;
|
|
62
|
+
deliveryChannel?: string;
|
|
63
|
+
developmentCode?: string | null;
|
|
64
|
+
}
|
|
65
|
+
interface GatewayLoginResponse {
|
|
66
|
+
requiresTwoFactor: boolean;
|
|
67
|
+
twoFactor: GatewayTwoFactorChallenge | null;
|
|
68
|
+
tokens: GatewayAuthTokens;
|
|
69
|
+
user: GatewayUserDetails;
|
|
70
|
+
delegations?: unknown[];
|
|
71
|
+
}
|
|
72
|
+
interface GatewayLoginRequest {
|
|
73
|
+
userName: string;
|
|
74
|
+
password: string;
|
|
75
|
+
isEncrypted?: boolean;
|
|
76
|
+
deviceToken?: string;
|
|
77
|
+
recaptchaToken?: string;
|
|
78
|
+
recaptchaAction?: string;
|
|
79
|
+
}
|
|
80
|
+
interface GatewayVerifyMfaRequest {
|
|
81
|
+
userId: string;
|
|
82
|
+
tempSessionId: string;
|
|
83
|
+
code: string;
|
|
84
|
+
deviceToken?: string;
|
|
85
|
+
}
|
|
86
|
+
interface GatewayResendMfaRequest {
|
|
87
|
+
userId: string;
|
|
88
|
+
tempSessionId: string;
|
|
89
|
+
}
|
|
90
|
+
interface GatewayRefreshRequest {
|
|
91
|
+
refreshToken: string;
|
|
92
|
+
deviceToken?: string;
|
|
93
|
+
}
|
|
94
|
+
interface GatewayLogoutRequest {
|
|
95
|
+
refreshToken?: string | null;
|
|
96
|
+
deviceToken?: string;
|
|
97
|
+
}
|
|
98
|
+
type GatewayPlatform = 'web' | 'mobile';
|
|
99
|
+
type GatewaySsoProtocol = 'oidc' | 'saml2' | 'nafath' | string;
|
|
100
|
+
type GatewaySsoFlow = 'browser_redirect' | 'push' | string;
|
|
101
|
+
interface GatewaySsoProvider {
|
|
102
|
+
key: string;
|
|
103
|
+
displayName: string;
|
|
104
|
+
protocol: GatewaySsoProtocol;
|
|
105
|
+
flow: GatewaySsoFlow;
|
|
106
|
+
startUrl: string;
|
|
107
|
+
startMethod: 'GET' | 'POST' | string;
|
|
108
|
+
tokenExchangeUrl: string;
|
|
109
|
+
requiresIdentifier: boolean;
|
|
110
|
+
identifierType: '' | 'national_or_resident_id' | string;
|
|
111
|
+
enabled: boolean;
|
|
112
|
+
supportsMobile: boolean;
|
|
113
|
+
allowTokenExchange: boolean;
|
|
114
|
+
}
|
|
115
|
+
interface GatewaySsoProvidersData {
|
|
116
|
+
providers: GatewaySsoProvider[];
|
|
117
|
+
}
|
|
118
|
+
interface GatewaySsoExchangeRequest {
|
|
119
|
+
code: string;
|
|
120
|
+
state: string;
|
|
121
|
+
deviceToken?: string;
|
|
122
|
+
}
|
|
123
|
+
interface GatewayExternalTokenExchangeRequest {
|
|
124
|
+
providerKey: string;
|
|
125
|
+
subjectToken: string;
|
|
126
|
+
subjectTokenType: 'urn:ietf:params:oauth:token-type:access_token';
|
|
127
|
+
deviceToken?: string;
|
|
128
|
+
}
|
|
129
|
+
interface GatewayNafathStartRequest {
|
|
130
|
+
nationalId: string;
|
|
131
|
+
platform: GatewayPlatform;
|
|
132
|
+
returnUrl: string;
|
|
133
|
+
clientState: string;
|
|
134
|
+
}
|
|
135
|
+
interface GatewayNafathStartData {
|
|
136
|
+
requestId: string;
|
|
137
|
+
statusToken: string;
|
|
138
|
+
random: string;
|
|
139
|
+
expiresAtUtc: string;
|
|
140
|
+
pollIntervalSeconds: number;
|
|
141
|
+
statusUrl: string;
|
|
142
|
+
}
|
|
143
|
+
interface GatewayNafathStatusRequest {
|
|
144
|
+
requestId: string;
|
|
145
|
+
statusToken: string;
|
|
146
|
+
}
|
|
147
|
+
interface GatewayNafathStatusData {
|
|
148
|
+
status: 'WAITING' | 'COMPLETED' | 'REJECTED' | 'EXPIRED' | 'FAILED' | string;
|
|
149
|
+
code?: string;
|
|
150
|
+
state?: string;
|
|
151
|
+
expiresAtUtc?: string;
|
|
152
|
+
pollIntervalSeconds?: number;
|
|
153
|
+
errorCode?: string;
|
|
154
|
+
message?: string;
|
|
155
|
+
}
|
|
156
|
+
interface GatewayMappedTokens {
|
|
157
|
+
accessToken: string;
|
|
158
|
+
refreshToken: string;
|
|
159
|
+
accessTokenExpiresAt: string | null;
|
|
160
|
+
refreshTokenExpiresAt: string | null;
|
|
161
|
+
}
|
|
162
|
+
interface GatewayMappedUser {
|
|
163
|
+
expireAt?: string;
|
|
164
|
+
user: GatewayUserDetails;
|
|
165
|
+
mainUser?: GatewayUserDetails;
|
|
166
|
+
token?: string;
|
|
167
|
+
refreshToken?: string;
|
|
168
|
+
accessToken?: string;
|
|
169
|
+
accessTokenExpiresAt?: string;
|
|
170
|
+
refreshTokenExpiresAt?: string;
|
|
171
|
+
delegatedToken?: string;
|
|
172
|
+
delegations?: unknown[];
|
|
173
|
+
isAdmin?: boolean;
|
|
174
|
+
twoFactorRequired?: boolean;
|
|
175
|
+
tempSessionId?: string;
|
|
176
|
+
id?: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
declare const GATEWAY_AUTH_DEVICE_TOKEN = "web-app";
|
|
180
|
+
declare const GATEWAY_AUTH_ENDPOINTS: {
|
|
181
|
+
readonly login: "auth/login";
|
|
182
|
+
readonly verifyMfa: "auth/2fa/verify";
|
|
183
|
+
readonly resendMfa: "auth/2fa/resend";
|
|
184
|
+
readonly refresh: "auth/refresh";
|
|
185
|
+
readonly logout: "auth/logout";
|
|
186
|
+
readonly ssoProviders: "auth/sso/providers";
|
|
187
|
+
readonly ssoExchange: "auth/sso/exchange";
|
|
188
|
+
readonly ssoTokenExchange: "auth/sso/token-exchange";
|
|
189
|
+
readonly nafathStart: (providerKey: string) => string;
|
|
190
|
+
readonly nafathStatus: (providerKey: string) => string;
|
|
191
|
+
readonly ssoStart: (providerKey: string) => string;
|
|
192
|
+
};
|
|
193
|
+
declare function isExpired(expireAt?: string | null): boolean;
|
|
194
|
+
declare function resolveApiDateValue(value?: GatewayApiDateValue | null): string | null;
|
|
195
|
+
declare function mapGatewayTokens(tokens: GatewayAuthTokens | GatewayRefreshData): GatewayMappedTokens;
|
|
196
|
+
declare function mapGatewayUser(user: GatewayUserDetails, tokenData: GatewayMappedTokens, delegations?: unknown[]): GatewayMappedUser;
|
|
197
|
+
declare function hasGatewayTokens(tokens?: Partial<GatewayAuthTokens | GatewayRefreshData> | null): boolean;
|
|
198
|
+
declare function getGatewayErrorMessage(error: unknown, fallback: string): string;
|
|
199
|
+
declare function normalizeGatewayBase(baseUrl?: string | null): string;
|
|
200
|
+
declare function buildGatewayUrl(gatewayApiBaseUrl: string | undefined | null, path: string): string;
|
|
201
|
+
interface BuildSsoStartUrlOptions {
|
|
202
|
+
gatewayApiBaseUrl: string;
|
|
203
|
+
provider: GatewaySsoProvider;
|
|
204
|
+
returnUrl: string;
|
|
205
|
+
clientState: string;
|
|
206
|
+
platform?: 'web' | 'mobile';
|
|
207
|
+
}
|
|
208
|
+
declare function buildSsoStartUrl({ gatewayApiBaseUrl, provider, returnUrl, clientState, platform, }: BuildSsoStartUrlOptions): string;
|
|
209
|
+
declare function createSecureClientState(): string;
|
|
210
|
+
|
|
211
|
+
declare class GatewaySsoSession {
|
|
212
|
+
createAndStoreState(): string;
|
|
213
|
+
getPendingState(): string | null;
|
|
214
|
+
clearPendingState(): void;
|
|
215
|
+
consumeExpectedState(state: string | null): boolean;
|
|
216
|
+
clearCallbackQuery(path?: string): void;
|
|
217
|
+
clearAll(): void;
|
|
218
|
+
private get storage();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export { GATEWAY_AUTH_DEVICE_TOKEN, GATEWAY_AUTH_ENDPOINTS, GatewaySsoSession, buildGatewayUrl, buildSsoStartUrl, createSecureClientState, getGatewayErrorMessage, hasGatewayTokens, isExpired, mapGatewayTokens, mapGatewayUser, normalizeGatewayBase, resolveApiDateValue };
|
|
222
|
+
export type { BuildSsoStartUrlOptions, GatewayApiDateValue, GatewayAuthTokens, GatewayExternalTokenExchangeRequest, GatewayLoginRequest, GatewayLoginResponse, GatewayLogoutRequest, GatewayMappedTokens, GatewayMappedUser, GatewayNafathStartData, GatewayNafathStartRequest, GatewayNafathStatusData, GatewayNafathStatusRequest, GatewayPlatform, GatewayRefreshData, GatewayRefreshRequest, GatewayResendMfaRequest, GatewayResponse, GatewaySsoExchangeRequest, GatewaySsoFlow, GatewaySsoProtocol, GatewaySsoProvider, GatewaySsoProvidersData, GatewayTwoFactorChallenge, GatewayUserDetails, GatewayVerifyMfaRequest };
|