@astram/frontend-core 0.6.1 → 0.8.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/dist/auth/auditService.d.ts +17 -1
- package/dist/auth/auditService.d.ts.map +1 -1
- package/dist/auth/auditService.js.map +1 -1
- package/dist/auth/authService.d.ts +56 -10
- package/dist/auth/authService.d.ts.map +1 -1
- package/dist/auth/authService.js +103 -14
- package/dist/auth/authService.js.map +1 -1
- package/dist/auth/identityService.d.ts +132 -10
- package/dist/auth/identityService.d.ts.map +1 -1
- package/dist/auth/identityService.js +275 -43
- package/dist/auth/identityService.js.map +1 -1
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/restriction.d.ts +16 -0
- package/dist/auth/restriction.d.ts.map +1 -0
- package/dist/auth/restriction.js +23 -0
- package/dist/auth/restriction.js.map +1 -0
- package/dist/auth/securityPolicyService.d.ts +93 -0
- package/dist/auth/securityPolicyService.d.ts.map +1 -0
- package/dist/auth/securityPolicyService.js +104 -0
- package/dist/auth/securityPolicyService.js.map +1 -0
- package/package.json +6 -1
|
@@ -29,9 +29,25 @@ export interface AuditQuery {
|
|
|
29
29
|
page?: number;
|
|
30
30
|
limit?: number;
|
|
31
31
|
}
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Who wrote an audit row: a user, a service account (API key), a framework operation (org
|
|
34
|
+
* bootstrap, audit retention prune), or an id found nowhere (shown as "Deleted user").
|
|
35
|
+
*/
|
|
36
|
+
export type AuditActorKind = 'user' | 'service_account' | 'operation' | 'unknown';
|
|
37
|
+
/**
|
|
38
|
+
* A single resolved audit row (`GET /identity/audit` `data[]`). Labels only, never raw ids. The
|
|
39
|
+
* named fields are optional so an older server (no `actorKind`) still type-checks; the index
|
|
40
|
+
* signature keeps any further server field readable.
|
|
41
|
+
*/
|
|
33
42
|
export interface AuditRecord {
|
|
34
43
|
id?: string;
|
|
44
|
+
occurredAt?: number;
|
|
45
|
+
actorLabel?: string;
|
|
46
|
+
/** Absent on servers before KI #140: treat as `'user'`. */
|
|
47
|
+
actorKind?: AuditActorKind;
|
|
48
|
+
action?: string;
|
|
49
|
+
tenantLabel?: string;
|
|
50
|
+
detail?: Record<string, unknown>;
|
|
35
51
|
[key: string]: unknown;
|
|
36
52
|
}
|
|
37
53
|
export type ListAuditResult = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auditService.d.ts","sourceRoot":"","sources":["../../src/auth/auditService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,
|
|
1
|
+
{"version":3,"file":"auditService.d.ts","sourceRoot":"","sources":["../../src/auth/auditService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,iBAAiB,GAAG,WAAW,GAAG,SAAS,CAAC;AAElF;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC7E;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,IAAI,CACF,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,UAAU,EAClB,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,eAAe,CAAA;KAAE,GAClC,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY,CA2EjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auditService.js","sourceRoot":"","sources":["../../src/auth/auditService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auditService.js","sourceRoot":"","sources":["../../src/auth/auditService.ts"],"names":[],"mappings":"AAoEA,MAAM,UAAU,kBAAkB,CAAC,IAAgB;IACjD;;;;;;;;;;OAUG;IACH,SAAS,eAAe,CAAC,KAAkB;QACzC,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;gBAC1D,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,SAAS,IAAI,CACX,CAAqB,EACrB,OAAe;QAEf,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAC;QACzF,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzD,CAAC;IAED,OAAO;QACL;;;;;;WAMG;QACH,KAAK,CAAC,IAAI,CACR,WAAmB,EACnB,KAAkB,EAClB,IAAmC;YAEnC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE;gBACnE,WAAW,EAAE,WAAW;gBACxB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjD,CAAC,CAAC;YACH,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;gBACT,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAKzB,CAAC;gBACF,OAAO;oBACL,EAAE,EAAE,IAAI;oBACR,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;oBACrB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC;oBACtB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC;oBACnC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK,EAAE,KAAK,IAAI,EAAE;iBACxC,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC,CAAC,EAAE,+BAA+B,CAAC,CAAC;QAClD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -7,12 +7,13 @@
|
|
|
7
7
|
* runs unchanged on web today and React Native next.
|
|
8
8
|
*
|
|
9
9
|
* Framework auth routes (server-side, framework-owned):
|
|
10
|
-
*
|
|
10
|
+
* GET /auth/login-options → { signInWith, captcha } (public)
|
|
11
|
+
* POST /auth/login { identityHint, password, captchaToken? } → { session, tokens } | { mfaRequired, challengeToken }
|
|
11
12
|
* POST /auth/mfa { challengeToken, factor, code } → { session, tokens }
|
|
12
13
|
* POST /auth/refresh { refreshToken } → { session, tokens }
|
|
13
|
-
* POST /auth/logout { sessionId }
|
|
14
|
-
* POST /auth/forgot-password { identityHint }
|
|
15
|
-
* POST /auth/reset-password { token, newPassword } → 204 | 400 | 422 | 501
|
|
14
|
+
* POST /auth/logout { sessionId, refreshToken? } (+ bearer) → 204
|
|
15
|
+
* POST /auth/forgot-password { identityHint, captchaToken? } → 204 (always)
|
|
16
|
+
* POST /auth/reset-password { token, newPassword, captchaToken? } → 204 | 400 | 422 | 501
|
|
16
17
|
* POST /auth/confirm-email { token } → 200 { ok } | 400 | 409 | 429 | 503
|
|
17
18
|
*
|
|
18
19
|
* Every method resolves to a plain result object (never throws), so views stay dumb.
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
* every result branch are unchanged; only types were added.
|
|
22
23
|
*/
|
|
23
24
|
import type { AbortSignalLike, HttpClient } from '../http/types.js';
|
|
24
|
-
import type { Session, SessionTokens } from './session.js';
|
|
25
|
+
import type { Session, SessionState, SessionTokens } from './session.js';
|
|
25
26
|
/** Shape of a display profile returned by GET /auth/me. */
|
|
26
27
|
export interface AuthProfile {
|
|
27
28
|
id: string;
|
|
@@ -35,8 +36,42 @@ export interface AuthProfile {
|
|
|
35
36
|
id: string;
|
|
36
37
|
name: string;
|
|
37
38
|
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Auth capabilities R2.4: when a security policy requires 2FA and the user is still in the grace
|
|
41
|
+
* period, the deadline to enrol (ISO-8601 UTC string). Absent otherwise. Drives the grace banner.
|
|
42
|
+
*/
|
|
43
|
+
mfaEnrollmentDeadline?: string;
|
|
38
44
|
[key: string]: unknown;
|
|
39
45
|
}
|
|
46
|
+
/** How users may type their sign-in name (R1.8): email always; a login name when enabled. */
|
|
47
|
+
export type SignInMethod = 'email' | 'username';
|
|
48
|
+
/** The CAPTCHA providers the server can name (R7.1). */
|
|
49
|
+
export type CaptchaProvider = 'turnstile' | 'recaptcha-v3' | 'recaptcha-v2';
|
|
50
|
+
/** `adaptive`: a challenge only after repeated failures; `always`: every attempt (R7.3). */
|
|
51
|
+
export type CaptchaMode = 'adaptive' | 'always';
|
|
52
|
+
/** The public CAPTCHA settings from `GET /auth/login-options` (the site key, never the secret). */
|
|
53
|
+
export interface CaptchaOptions {
|
|
54
|
+
provider: CaptchaProvider;
|
|
55
|
+
siteKey: string;
|
|
56
|
+
mode: CaptchaMode;
|
|
57
|
+
}
|
|
58
|
+
/** `GET /auth/login-options` (R7.3, R13.2): the login label and the CAPTCHA widget settings. */
|
|
59
|
+
export type LoginOptionsResult = {
|
|
60
|
+
ok: true;
|
|
61
|
+
signInWith: SignInMethod[];
|
|
62
|
+
captcha: CaptchaOptions | null;
|
|
63
|
+
} | {
|
|
64
|
+
ok: false;
|
|
65
|
+
status: number;
|
|
66
|
+
error: string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Optional CAPTCHA token for login, forgot-password and reset-password (R7.2). Send it once the
|
|
70
|
+
* server answered `captchaRequired: true` (or always, in `always` mode).
|
|
71
|
+
*/
|
|
72
|
+
export interface CaptchaOpts {
|
|
73
|
+
captchaToken?: string;
|
|
74
|
+
}
|
|
40
75
|
/**
|
|
41
76
|
* The caller's own coarse auth-facts projection, as inlined into a login/mfa success
|
|
42
77
|
* body by the framework (same shape as `GET /identity/auth-facts`). ADDITIVE +
|
|
@@ -64,9 +99,12 @@ export type LoginResult = {
|
|
|
64
99
|
} | {
|
|
65
100
|
ok: 'mfa';
|
|
66
101
|
challengeToken: string;
|
|
67
|
-
}
|
|
102
|
+
}
|
|
103
|
+
/** `captchaRequired`: the server wants a CAPTCHA token on the next attempt (R7.3). */
|
|
104
|
+
| {
|
|
68
105
|
ok: false;
|
|
69
106
|
error: string;
|
|
107
|
+
captchaRequired?: true;
|
|
70
108
|
};
|
|
71
109
|
export type CompleteMfaResult = {
|
|
72
110
|
ok: true;
|
|
@@ -106,12 +144,14 @@ export type MeResult = {
|
|
|
106
144
|
export type RequestResetResult = {
|
|
107
145
|
ok: true;
|
|
108
146
|
};
|
|
147
|
+
/** `captchaRequired`: retry with a CAPTCHA token (the message stays the generic one). */
|
|
109
148
|
export type ResetPasswordResult = {
|
|
110
149
|
ok: true;
|
|
111
150
|
} | {
|
|
112
151
|
ok: false;
|
|
113
152
|
status: number;
|
|
114
153
|
error: string;
|
|
154
|
+
captchaRequired?: true;
|
|
115
155
|
};
|
|
116
156
|
/** `status: 0` = the server could not be reached. */
|
|
117
157
|
export type ConfirmEmailResult = {
|
|
@@ -122,16 +162,22 @@ export type ConfirmEmailResult = {
|
|
|
122
162
|
error: string;
|
|
123
163
|
};
|
|
124
164
|
export interface AuthService {
|
|
125
|
-
|
|
165
|
+
/** Public sign-in settings (R13.2): sign-in methods and CAPTCHA widget settings. */
|
|
166
|
+
loginOptions(): Promise<LoginOptionsResult>;
|
|
167
|
+
login(identityHint: string, password: string, opts?: CaptchaOpts): Promise<LoginResult>;
|
|
126
168
|
completeMfa(challengeToken: string, code: string, factor?: string): Promise<CompleteMfaResult>;
|
|
127
169
|
/** `opts.signal` (additive) is forwarded to the transport so a hung refresh can be aborted. */
|
|
128
170
|
refresh(refreshToken: string, opts?: {
|
|
129
171
|
signal?: AbortSignalLike;
|
|
130
172
|
}): Promise<RefreshResult>;
|
|
131
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Pass the session state (`{ session, tokens }`) so the server gets proof of ownership
|
|
175
|
+
* (R15.1); a bare `sessionId` string is still accepted (no proof sent).
|
|
176
|
+
*/
|
|
177
|
+
logout(target: string | SessionState | null | undefined): Promise<LogoutResult>;
|
|
132
178
|
me(accessToken: string): Promise<MeResult>;
|
|
133
|
-
requestReset(identityHint: string): Promise<RequestResetResult>;
|
|
134
|
-
resetPassword(token: string, newPassword: string): Promise<ResetPasswordResult>;
|
|
179
|
+
requestReset(identityHint: string, opts?: CaptchaOpts): Promise<RequestResetResult>;
|
|
180
|
+
resetPassword(token: string, newPassword: string, opts?: CaptchaOpts): Promise<ResetPasswordResult>;
|
|
135
181
|
confirmEmail(token: string): Promise<ConfirmEmailResult>;
|
|
136
182
|
}
|
|
137
183
|
export declare function createAuthService(http: HttpClient): AuthService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authService.d.ts","sourceRoot":"","sources":["../../src/auth/authService.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"authService.d.ts","sourceRoot":"","sources":["../../src/auth/authService.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/authService.js
CHANGED
|
@@ -1,13 +1,66 @@
|
|
|
1
|
+
const SIGN_IN_METHODS = ['email', 'username'];
|
|
2
|
+
const CAPTCHA_PROVIDERS = ['turnstile', 'recaptcha-v3', 'recaptcha-v2'];
|
|
3
|
+
const CAPTCHA_MODES = ['adaptive', 'always'];
|
|
4
|
+
/** True when the failure body says the next attempt needs a CAPTCHA token. */
|
|
5
|
+
function captchaRequiredIn(data) {
|
|
6
|
+
return (data !== null &&
|
|
7
|
+
typeof data === 'object' &&
|
|
8
|
+
data.captcha === 'required');
|
|
9
|
+
}
|
|
10
|
+
/** Keep only a well-formed CAPTCHA block; anything else reads as "no CAPTCHA". */
|
|
11
|
+
function captchaOptionsOf(raw) {
|
|
12
|
+
if (raw === null || typeof raw !== 'object')
|
|
13
|
+
return null;
|
|
14
|
+
const { provider, siteKey, mode } = raw;
|
|
15
|
+
if (!CAPTCHA_PROVIDERS.includes(provider))
|
|
16
|
+
return null;
|
|
17
|
+
if (typeof siteKey !== 'string' || siteKey.length === 0)
|
|
18
|
+
return null;
|
|
19
|
+
if (!CAPTCHA_MODES.includes(mode))
|
|
20
|
+
return null;
|
|
21
|
+
return { provider: provider, siteKey, mode: mode };
|
|
22
|
+
}
|
|
23
|
+
/** `captchaToken` as a body fragment, only when set. */
|
|
24
|
+
function captchaBody(opts) {
|
|
25
|
+
return opts?.captchaToken ? { captchaToken: opts.captchaToken } : {};
|
|
26
|
+
}
|
|
1
27
|
export function createAuthService(http) {
|
|
2
28
|
return {
|
|
29
|
+
/**
|
|
30
|
+
* Read the public sign-in settings (framework `GET /auth/login-options`, no session, so the
|
|
31
|
+
* call is anonymous). Resolves to `{ ok: true, signInWith, captcha }`: `signInWith` lists the
|
|
32
|
+
* accepted name kinds (the login label is "Email" or "Email or username"); `captcha` is the
|
|
33
|
+
* provider, site key and mode, or `null` when CAPTCHA is off. Unknown methods are dropped
|
|
34
|
+
* (an empty list reads as `['email']`) and a malformed CAPTCHA block reads as `null`.
|
|
35
|
+
*/
|
|
36
|
+
async loginOptions() {
|
|
37
|
+
const r = await http.get('/auth/login-options', { anonymous: true });
|
|
38
|
+
if (r.ok) {
|
|
39
|
+
const data = (r.data ?? {});
|
|
40
|
+
const methods = Array.isArray(data.signInWith)
|
|
41
|
+
? SIGN_IN_METHODS.filter((m) => data.signInWith.includes(m))
|
|
42
|
+
: [];
|
|
43
|
+
return {
|
|
44
|
+
ok: true,
|
|
45
|
+
signInWith: methods.length > 0 ? methods : ['email'],
|
|
46
|
+
captcha: captchaOptionsOf(data.captcha),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (r.status === 0) {
|
|
50
|
+
return { ok: false, status: 0, error: 'Cannot reach the server. Is it running?' };
|
|
51
|
+
}
|
|
52
|
+
return { ok: false, status: r.status, error: 'Could not load sign-in options.' };
|
|
53
|
+
},
|
|
3
54
|
/**
|
|
4
55
|
* Log in. Resolves to:
|
|
5
56
|
* { ok: true, session, tokens } — authenticated
|
|
6
57
|
* { ok: 'mfa', challengeToken } — second factor required
|
|
7
58
|
* { ok: false, error } — bad credentials / unavailable / unreachable
|
|
59
|
+
* (+ `captchaRequired: true` when the 401 says the next attempt needs a CAPTCHA token)
|
|
60
|
+
* `opts.captchaToken` is sent only when set.
|
|
8
61
|
*/
|
|
9
|
-
async login(identityHint, password) {
|
|
10
|
-
const r = await http.post('/auth/login', { identityHint, password });
|
|
62
|
+
async login(identityHint, password, opts) {
|
|
63
|
+
const r = await http.post('/auth/login', { identityHint, password, ...captchaBody(opts) });
|
|
11
64
|
const data = r.data;
|
|
12
65
|
if (r.status === 0)
|
|
13
66
|
return { ok: false, error: 'Cannot reach the server. Is it running?' };
|
|
@@ -26,8 +79,13 @@ export function createAuthService(http) {
|
|
|
26
79
|
...(data.authFacts ? { authFacts: data.authFacts } : {}),
|
|
27
80
|
};
|
|
28
81
|
}
|
|
29
|
-
if (r.status === 401)
|
|
30
|
-
return {
|
|
82
|
+
if (r.status === 401) {
|
|
83
|
+
return {
|
|
84
|
+
ok: false,
|
|
85
|
+
error: 'Invalid username or password.',
|
|
86
|
+
...(captchaRequiredIn(r.data) ? { captchaRequired: true } : {}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
31
89
|
if (r.status === 503) {
|
|
32
90
|
return { ok: false, error: 'Authentication is temporarily unavailable. Please try again.' };
|
|
33
91
|
}
|
|
@@ -83,10 +141,27 @@ export function createAuthService(http) {
|
|
|
83
141
|
}
|
|
84
142
|
return { ok: false, status: r.status, error: 'Session expired. Please sign in again.' };
|
|
85
143
|
},
|
|
86
|
-
/**
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Log out (revoke the session). Always resolves — logout must never block a UI.
|
|
146
|
+
*
|
|
147
|
+
* Pass the session state (`{ session, tokens }`) so the server can verify the caller owns
|
|
148
|
+
* the session (R15.1): the body carries `{ sessionId, refreshToken }` and the access token
|
|
149
|
+
* goes as `Authorization: Bearer`, each only when held. A bare `sessionId` string still
|
|
150
|
+
* works (sends `{ sessionId }` only), but a server with `logoutRequiresProof: true` then
|
|
151
|
+
* revokes nothing.
|
|
152
|
+
*/
|
|
153
|
+
async logout(target) {
|
|
154
|
+
if (typeof target === 'string') {
|
|
155
|
+
if (target)
|
|
156
|
+
await http.post('/auth/logout', { sessionId: target });
|
|
157
|
+
return { ok: true };
|
|
158
|
+
}
|
|
159
|
+
const sessionId = target?.session?.sessionId;
|
|
160
|
+
if (!sessionId)
|
|
161
|
+
return { ok: true };
|
|
162
|
+
const refreshToken = target?.tokens?.refreshToken;
|
|
163
|
+
const accessToken = target?.tokens?.accessToken;
|
|
164
|
+
await http.post('/auth/logout', refreshToken ? { sessionId, refreshToken } : { sessionId }, accessToken ? { bearerToken: accessToken } : undefined);
|
|
90
165
|
return { ok: true };
|
|
91
166
|
},
|
|
92
167
|
/**
|
|
@@ -119,9 +194,10 @@ export function createAuthService(http) {
|
|
|
119
194
|
* `{ ok: true }` — the UI shows the SAME neutral confirmation regardless. Never
|
|
120
195
|
* reveals whether the account exists.
|
|
121
196
|
* @param identityHint username or email
|
|
197
|
+
* @param opts.captchaToken sent only when set (the server checks it after answering 204)
|
|
122
198
|
*/
|
|
123
|
-
async requestReset(identityHint) {
|
|
124
|
-
await http.post('/auth/forgot-password', { identityHint });
|
|
199
|
+
async requestReset(identityHint, opts) {
|
|
200
|
+
await http.post('/auth/forgot-password', { identityHint, ...captchaBody(opts) });
|
|
125
201
|
// Mirror the server's anti-enumeration: report nothing about existence.
|
|
126
202
|
return { ok: true };
|
|
127
203
|
},
|
|
@@ -132,14 +208,27 @@ export function createAuthService(http) {
|
|
|
132
208
|
* { ok: false, status, error } — 400 (invalid/expired link),
|
|
133
209
|
* 422 (requirements), 501 (not available)
|
|
134
210
|
* Never throws — the UI renders the message.
|
|
211
|
+
* A 400 that carries `captcha: 'required'` adds `captchaRequired: true` (retry with a token);
|
|
212
|
+
* the message stays the generic one.
|
|
135
213
|
* @param token the raw reset token from the emailed link
|
|
214
|
+
* @param opts.captchaToken sent only when set
|
|
136
215
|
*/
|
|
137
|
-
async resetPassword(token, newPassword) {
|
|
138
|
-
const r = await http.post('/auth/reset-password', {
|
|
216
|
+
async resetPassword(token, newPassword, opts) {
|
|
217
|
+
const r = await http.post('/auth/reset-password', {
|
|
218
|
+
token,
|
|
219
|
+
newPassword,
|
|
220
|
+
...captchaBody(opts),
|
|
221
|
+
});
|
|
139
222
|
if (r.status === 204)
|
|
140
223
|
return { ok: true };
|
|
141
|
-
if (r.status === 400)
|
|
142
|
-
return {
|
|
224
|
+
if (r.status === 400) {
|
|
225
|
+
return {
|
|
226
|
+
ok: false,
|
|
227
|
+
status: 400,
|
|
228
|
+
error: 'This reset link is invalid or has expired.',
|
|
229
|
+
...(captchaRequiredIn(r.data) ? { captchaRequired: true } : {}),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
143
232
|
if (r.status === 422)
|
|
144
233
|
return { ok: false, status: 422, error: 'New password does not meet the requirements.' };
|
|
145
234
|
if (r.status === 501)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authService.js","sourceRoot":"","sources":["../../src/auth/authService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authService.js","sourceRoot":"","sources":["../../src/auth/authService.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,12 +12,15 @@
|
|
|
12
12
|
*
|
|
13
13
|
* The server routes these hit (all `@Classified`, root-gated in Phase 2):
|
|
14
14
|
* GET/POST/PUT/DELETE /identity/companies[/:uuid]
|
|
15
|
+
* PUT /identity/companies/:uuid/parent
|
|
15
16
|
* GET/POST/PUT/DELETE /identity/roles[/:uuid]
|
|
16
17
|
* GET/POST/PUT/DELETE /identity/users[/:uuid]
|
|
18
|
+
* POST /identity/users/:uuid/{reset-mfa,unlock,end-sessions} (R11, body { code })
|
|
17
19
|
* GET/POST /identity/users/:userUuid/memberships
|
|
18
20
|
* PUT/DELETE /identity/memberships/:membershipUuid
|
|
19
21
|
* PUT /identity/memberships/:membershipUuid/postings
|
|
20
|
-
* GET
|
|
22
|
+
* GET/POST /identity/companies/:companyUuid/{departments,branches}
|
|
23
|
+
* PUT/DELETE /identity/{departments,branches}/:uuid (G-012)
|
|
21
24
|
*
|
|
22
25
|
* NO raw UUID is ever a display value — list rows carry `{ id, fields }` (the id is a
|
|
23
26
|
* key/param), membership cards carry `*Name` fields resolved server-side.
|
|
@@ -78,10 +81,27 @@ export interface Posting {
|
|
|
78
81
|
effectiveFrom?: string;
|
|
79
82
|
effectiveUntil?: string;
|
|
80
83
|
}
|
|
81
|
-
|
|
84
|
+
/**
|
|
85
|
+
* A department or branch row from a company-scoped catalog list (G-012): `uuid` is the option
|
|
86
|
+
* value, `name` the label (never render the uuid). `usedBy` is the number of assignments
|
|
87
|
+
* (postings) the caller can see that reference the row; it is absent when the caller cannot read
|
|
88
|
+
* postings. It is advisory: the server's delete still decides (409 when the row is in use).
|
|
89
|
+
*/
|
|
90
|
+
export interface OrgUnitRow extends IdentityRecord {
|
|
91
|
+
uuid?: string;
|
|
92
|
+
name?: string;
|
|
93
|
+
usedBy?: number;
|
|
94
|
+
}
|
|
95
|
+
/** Optional paging for a company-scoped catalog list; omit it to get every row (up to 1000). */
|
|
96
|
+
export interface OrgUnitListOpts {
|
|
97
|
+
page?: number;
|
|
98
|
+
limit?: number;
|
|
99
|
+
search?: string;
|
|
100
|
+
}
|
|
101
|
+
export type PagedListResult<R extends IdentityRecord = IdentityRecord> = {
|
|
82
102
|
ok: true;
|
|
83
103
|
total: number;
|
|
84
|
-
rows:
|
|
104
|
+
rows: R[];
|
|
85
105
|
page: number;
|
|
86
106
|
limit: number;
|
|
87
107
|
} | {
|
|
@@ -89,9 +109,9 @@ export type PagedListResult = {
|
|
|
89
109
|
status: number;
|
|
90
110
|
error: string;
|
|
91
111
|
};
|
|
92
|
-
export type GetRecordResult = {
|
|
112
|
+
export type GetRecordResult<R extends IdentityRecord = IdentityRecord> = {
|
|
93
113
|
ok: true;
|
|
94
|
-
record:
|
|
114
|
+
record: R | null;
|
|
95
115
|
} | {
|
|
96
116
|
ok: false;
|
|
97
117
|
status: number;
|
|
@@ -112,6 +132,75 @@ export type OkResult = {
|
|
|
112
132
|
status: number;
|
|
113
133
|
error: string;
|
|
114
134
|
};
|
|
135
|
+
/**
|
|
136
|
+
* Whether a user can sign in yet (G-010), computed by the server from the credential:
|
|
137
|
+
* `pending` = invited or created but no password set, `active` = has a password, `none` = no
|
|
138
|
+
* sign-in credential (no email or no company). User records from `listUsers` / `getUser` carry it
|
|
139
|
+
* as `signInStatus`; no credential data is ever exposed.
|
|
140
|
+
*/
|
|
141
|
+
export type SignInStatus = 'pending' | 'active' | 'none';
|
|
142
|
+
/**
|
|
143
|
+
* Whether a user must use 2FA and has it (auth capabilities R11.3): `enrolled` = has a confirmed
|
|
144
|
+
* device; `required` = a policy requires it and none is set up (signs in restricted); `grace` =
|
|
145
|
+
* required, still inside the grace period; `not_required` = no policy applies. Never device
|
|
146
|
+
* names, secrets or counts.
|
|
147
|
+
*/
|
|
148
|
+
export type UserMfaStatus = 'enrolled' | 'required' | 'grace' | 'not_required';
|
|
149
|
+
/** A user row from `listUsers` / `getUser`: the record plus the server-computed statuses. */
|
|
150
|
+
export interface UserRecord extends IdentityRecord {
|
|
151
|
+
signInStatus?: SignInStatus;
|
|
152
|
+
/** Absent when the server does not compute it (no MFA policy feature wired). */
|
|
153
|
+
mfaStatus?: UserMfaStatus;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Why an admin sign-in action (reset 2FA, unlock, end sessions; R11) failed. The UI branches on it:
|
|
157
|
+
* - `code_required` — no code was sent (400 `mfa_required`)
|
|
158
|
+
* - `invalid_code` — the admin's code was wrong or expired (400 `invalid_request`)
|
|
159
|
+
* - `admin_needs_mfa` — the admin has no 2FA set up and must enrol first (409 `mfa_required`)
|
|
160
|
+
* - `forbidden` — not allowed (yourself, no permission, another tenant, user not dominated; 403)
|
|
161
|
+
* - `not_authenticated` (401), `not_found` (404)
|
|
162
|
+
* - `rate_limited` — too many code attempts (429)
|
|
163
|
+
* - `unavailable` — nothing was changed, try again (503)
|
|
164
|
+
* - `partially_applied` — part of the action ran; retrying is safe (503 `partially_applied`)
|
|
165
|
+
* - `unreachable` — the server could not be reached (status 0)
|
|
166
|
+
* - `failed` — anything else
|
|
167
|
+
*/
|
|
168
|
+
export type SignInAdminFailureReason = 'code_required' | 'invalid_code' | 'admin_needs_mfa' | 'forbidden' | 'not_authenticated' | 'not_found' | 'rate_limited' | 'unavailable' | 'partially_applied' | 'unreachable' | 'failed';
|
|
169
|
+
/** Result of `resetUserMfa` / `unlockUser` / `endUserSessions`; `error` is a fixed message. */
|
|
170
|
+
export type SignInAdminResult = {
|
|
171
|
+
ok: true;
|
|
172
|
+
} | {
|
|
173
|
+
ok: false;
|
|
174
|
+
status: number;
|
|
175
|
+
reason: SignInAdminFailureReason;
|
|
176
|
+
error: string;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Build a `?page&limit&search&sortBy&sortOrder` query string from a DataTable
|
|
180
|
+
* options bag, omitting anything absent/empty so the server applies its defaults.
|
|
181
|
+
* Values are URL-encoded. Returns '' (no leading '?') when nothing is set.
|
|
182
|
+
*
|
|
183
|
+
* Built with plain `encodeURIComponent` (not `URLSearchParams`) — this package has
|
|
184
|
+
* no `lib.dom`/Node ambient types (it must run unchanged on web AND React Native,
|
|
185
|
+
* where `URLSearchParams` isn't guaranteed to exist), and every key here is set at
|
|
186
|
+
* most once, so a manual `key=value` join is byte-identical to the source's
|
|
187
|
+
* `URLSearchParams#toString()` output. Shared with the other identity services (not
|
|
188
|
+
* part of the package barrel).
|
|
189
|
+
*/
|
|
190
|
+
export declare function listQueryString(opts?: ListOpts): string;
|
|
191
|
+
/**
|
|
192
|
+
* `inviteUser` result. `emailed`: the server sent the set-password email. `link`: the one-time
|
|
193
|
+
* link, present only when the app opted in to returning it (`returnLinkToAdmin`); show it once.
|
|
194
|
+
*/
|
|
195
|
+
export type InviteUserResult = {
|
|
196
|
+
ok: true;
|
|
197
|
+
emailed: boolean;
|
|
198
|
+
link?: string;
|
|
199
|
+
} | {
|
|
200
|
+
ok: false;
|
|
201
|
+
status: number;
|
|
202
|
+
error: string;
|
|
203
|
+
};
|
|
115
204
|
export type ListPermissionCatalogResult = {
|
|
116
205
|
ok: true;
|
|
117
206
|
catalog: string[];
|
|
@@ -164,9 +253,26 @@ export type AddMembershipResult = {
|
|
|
164
253
|
status: number;
|
|
165
254
|
error: string;
|
|
166
255
|
};
|
|
256
|
+
/**
|
|
257
|
+
* A company-scoped catalog list. `total`/`page`/`limit` are present when the server sends them
|
|
258
|
+
* (G-012 servers always do), so a caller can tell whether `rows` is everything.
|
|
259
|
+
*/
|
|
167
260
|
export type ListCatalogRowsResult = {
|
|
168
261
|
ok: true;
|
|
169
|
-
rows:
|
|
262
|
+
rows: OrgUnitRow[];
|
|
263
|
+
total?: number;
|
|
264
|
+
page?: number;
|
|
265
|
+
limit?: number;
|
|
266
|
+
} | {
|
|
267
|
+
ok: false;
|
|
268
|
+
status: number;
|
|
269
|
+
error: string;
|
|
270
|
+
};
|
|
271
|
+
/** `createDepartment` / `createBranch` / `createCompanyRole` result: the new row's uuid (a key, never a label) and name. */
|
|
272
|
+
export type CreateOrgUnitResult = {
|
|
273
|
+
ok: true;
|
|
274
|
+
uuid: string;
|
|
275
|
+
name: string;
|
|
170
276
|
} | {
|
|
171
277
|
ok: false;
|
|
172
278
|
status: number;
|
|
@@ -178,11 +284,17 @@ export interface IdentityService {
|
|
|
178
284
|
createCompany(accessToken: string, name: string): Promise<CreateRecordResult>;
|
|
179
285
|
updateCompany(accessToken: string, uuid: string, patch?: Record<string, unknown>): Promise<OkResult>;
|
|
180
286
|
deleteCompany(accessToken: string, uuid: string): Promise<OkResult>;
|
|
287
|
+
/** Re-parent a company (`null` = top level, root only); the server checks cycles and reach. */
|
|
288
|
+
moveCompany(accessToken: string, uuid: string, parentUuid: string | null): Promise<OkResult>;
|
|
181
289
|
listRoles(accessToken: string, opts?: ListOpts): Promise<PagedListResult>;
|
|
182
290
|
getRole(accessToken: string, uuid: string): Promise<GetRecordResult>;
|
|
183
291
|
createRole(accessToken: string, name: string): Promise<CreateRecordResult>;
|
|
184
292
|
updateRole(accessToken: string, uuid: string, patch?: Record<string, unknown>): Promise<OkResult>;
|
|
185
293
|
deleteRole(accessToken: string, uuid: string): Promise<OkResult>;
|
|
294
|
+
/** One company's own roles (G-013), paged like `listRoles`; 404 when the company is out of reach. */
|
|
295
|
+
listCompanyRoles(accessToken: string, companyUuid: string, opts?: ListOpts): Promise<PagedListResult>;
|
|
296
|
+
/** Create a role owned by the company (G-013); a refusal keeps the server's message. */
|
|
297
|
+
createCompanyRole(accessToken: string, companyUuid: string, name: string): Promise<CreateOrgUnitResult>;
|
|
186
298
|
listPermissionCatalog(accessToken: string): Promise<ListPermissionCatalogResult>;
|
|
187
299
|
listGrantsSummary(accessToken: string, opts?: ListOpts): Promise<ListGrantsSummaryResult>;
|
|
188
300
|
listRolePermissions(accessToken: string, uuid: string): Promise<ListRolePermissionsResult>;
|
|
@@ -191,21 +303,31 @@ export interface IdentityService {
|
|
|
191
303
|
listAccessBundles(accessToken: string): Promise<ListAccessBundlesResult>;
|
|
192
304
|
grantAccessBundle(accessToken: string, uuid: string, key: string): Promise<OkResult>;
|
|
193
305
|
revokeAccessBundle(accessToken: string, uuid: string, key: string): Promise<OkResult>;
|
|
194
|
-
listUsers(accessToken: string, opts?: ListOpts): Promise<PagedListResult
|
|
195
|
-
getUser(accessToken: string, uuid: string): Promise<GetRecordResult
|
|
306
|
+
listUsers(accessToken: string, opts?: ListOpts): Promise<PagedListResult<UserRecord>>;
|
|
307
|
+
getUser(accessToken: string, uuid: string): Promise<GetRecordResult<UserRecord>>;
|
|
196
308
|
createUser(accessToken: string, input?: {
|
|
197
309
|
username?: string;
|
|
198
310
|
email?: string;
|
|
199
311
|
}): Promise<CreateRecordResult>;
|
|
200
312
|
updateUser(accessToken: string, uuid: string, patch?: Record<string, unknown>): Promise<OkResult>;
|
|
201
313
|
deleteUser(accessToken: string, uuid: string): Promise<OkResult>;
|
|
314
|
+
inviteUser(accessToken: string, userUuid: string): Promise<InviteUserResult>;
|
|
315
|
+
resetUserMfa(accessToken: string, userUuid: string, code: string): Promise<SignInAdminResult>;
|
|
316
|
+
unlockUser(accessToken: string, userUuid: string, code: string): Promise<SignInAdminResult>;
|
|
317
|
+
endUserSessions(accessToken: string, userUuid: string, code: string): Promise<SignInAdminResult>;
|
|
202
318
|
getUserMemberships(accessToken: string, userUuid: string): Promise<GetUserMembershipsResult>;
|
|
203
319
|
addMembership(accessToken: string, userUuid: string, companyUuid: string): Promise<AddMembershipResult>;
|
|
204
320
|
setMembershipActive(accessToken: string, membershipUuid: string, userUuid: string): Promise<OkResult>;
|
|
205
321
|
removeMembership(accessToken: string, membershipUuid: string): Promise<OkResult>;
|
|
206
322
|
replacePostings(accessToken: string, membershipUuid: string, postings: Posting[]): Promise<OkResult>;
|
|
207
|
-
listDepartments(accessToken: string, companyUuid: string): Promise<ListCatalogRowsResult>;
|
|
208
|
-
listBranches(accessToken: string, companyUuid: string): Promise<ListCatalogRowsResult>;
|
|
323
|
+
listDepartments(accessToken: string, companyUuid: string, opts?: OrgUnitListOpts): Promise<ListCatalogRowsResult>;
|
|
324
|
+
listBranches(accessToken: string, companyUuid: string, opts?: OrgUnitListOpts): Promise<ListCatalogRowsResult>;
|
|
325
|
+
createDepartment(accessToken: string, companyUuid: string, name: string): Promise<CreateOrgUnitResult>;
|
|
326
|
+
renameDepartment(accessToken: string, uuid: string, name: string): Promise<OkResult>;
|
|
327
|
+
deleteDepartment(accessToken: string, uuid: string): Promise<OkResult>;
|
|
328
|
+
createBranch(accessToken: string, companyUuid: string, name: string): Promise<CreateOrgUnitResult>;
|
|
329
|
+
renameBranch(accessToken: string, uuid: string, name: string): Promise<OkResult>;
|
|
330
|
+
deleteBranch(accessToken: string, uuid: string): Promise<OkResult>;
|
|
209
331
|
}
|
|
210
332
|
export declare function createIdentityService(http: HttpClient): IdentityService;
|
|
211
333
|
//# sourceMappingURL=identityService.d.ts.map
|