@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.
@@ -0,0 +1,93 @@
1
+ /**
2
+ * createSecurityPolicyService — platform-agnostic calls to the identity feature's mandatory-2FA
3
+ * policies (auth capabilities R2.1, R2.2, R2.6, R2.9). Like the other identity services it takes
4
+ * an injected HTTP client, carries no platform code and passes the bearer token per call. Every
5
+ * method resolves to a plain result object (never throws): `{ ok:true, ... }` on success,
6
+ * `{ ok:false, status, error }` on any non-2xx (0 = unreachable, 401 = not authenticated,
7
+ * 403 = denied (the server's fixed message when it gives one, e.g. lowering a policy needs more
8
+ * access), 400/409 = the server's fixed message, 404 = not found, 503 = try again, else generic).
9
+ *
10
+ * Server routes (all `@Classified` on `security_policy`, `identity:security_policy:<action>`):
11
+ * GET /identity/security-policies[?page&limit&search&sortBy&sortOrder] → { total, rows, page, limit }
12
+ * GET /identity/security-policies/:uuid → the record (empty when walled)
13
+ * POST /identity/security-policies { scopeNodeUuid?, platform?, targetKind, targetValue?, graceDays? } → { id }
14
+ * PUT /identity/security-policies/:uuid { targetValue?, graceDays? } → { success: true }
15
+ * DELETE /identity/security-policies/:uuid → { success: true }
16
+ *
17
+ * The scope node, platform flag and kind are fixed at create; changing them is a delete plus a
18
+ * create. Platform-floor rows are root only and never visible to other admins. `scopeNodeUuid`,
19
+ * a role `targetValue` and `createdBy` are ids: resolve them to names before display.
20
+ */
21
+ import type { HttpClient } from '../http/types.js';
22
+ import { type ListOpts } from './identityService.js';
23
+ /** `tenant`: everyone in the node's subtree; `role`: holders of a role; `permission`: holders of a key. */
24
+ export type SecurityPolicyTargetKind = 'tenant' | 'role' | 'permission';
25
+ /** The stored fields of one policy (engine field keys). */
26
+ export interface SecurityPolicyFields {
27
+ uuid?: string;
28
+ /** The company node the policy covers with its subtree; `null` on a platform-floor row. */
29
+ scopeNodeUuid?: string | null;
30
+ /** Platform floor (root only). */
31
+ platform?: boolean;
32
+ targetKind?: SecurityPolicyTargetKind;
33
+ /** Role uuid (`role`) or permission key / wildcard such as `identity:*` (`permission`); `null` for `tenant`. */
34
+ targetValue?: string | null;
35
+ /** 0–14. */
36
+ graceDays?: number;
37
+ createdBy?: string;
38
+ createdAtMs?: number;
39
+ updatedAtMs?: number;
40
+ [key: string]: unknown;
41
+ }
42
+ /** One policy as the server returns it (`{ id, fields }`); `id` is a key, never a display value. */
43
+ export interface SecurityPolicyRecord {
44
+ id: string;
45
+ fields: SecurityPolicyFields;
46
+ [key: string]: unknown;
47
+ }
48
+ /** Create body. Omit `scopeNodeUuid` for the caller's active organisation; `platform: true` is root only. */
49
+ export interface CreateSecurityPolicyBody {
50
+ scopeNodeUuid?: string;
51
+ platform?: boolean;
52
+ targetKind: SecurityPolicyTargetKind;
53
+ targetValue?: string | null;
54
+ graceDays?: number;
55
+ }
56
+ /** Update body: only the target value and the grace period can change. */
57
+ export interface UpdateSecurityPolicyBody {
58
+ targetValue?: string | null;
59
+ graceDays?: number;
60
+ }
61
+ type Failure = {
62
+ ok: false;
63
+ status: number;
64
+ error: string;
65
+ };
66
+ export type SecurityPolicyListResult = {
67
+ ok: true;
68
+ total: number;
69
+ rows: SecurityPolicyRecord[];
70
+ page: number;
71
+ limit: number;
72
+ } | Failure;
73
+ export type SecurityPolicyGetResult = {
74
+ ok: true;
75
+ policy: SecurityPolicyRecord | null;
76
+ } | Failure;
77
+ export type SecurityPolicyCreateResult = {
78
+ ok: true;
79
+ id: string | undefined;
80
+ } | Failure;
81
+ export type SecurityPolicyMutateResult = {
82
+ ok: true;
83
+ } | Failure;
84
+ export interface SecurityPolicyService {
85
+ list(accessToken: string, opts?: ListOpts): Promise<SecurityPolicyListResult>;
86
+ get(accessToken: string, uuid: string): Promise<SecurityPolicyGetResult>;
87
+ create(accessToken: string, body: CreateSecurityPolicyBody): Promise<SecurityPolicyCreateResult>;
88
+ update(accessToken: string, uuid: string, body: UpdateSecurityPolicyBody): Promise<SecurityPolicyMutateResult>;
89
+ remove(accessToken: string, uuid: string): Promise<SecurityPolicyMutateResult>;
90
+ }
91
+ export declare function createSecurityPolicyService(http: HttpClient): SecurityPolicyService;
92
+ export {};
93
+ //# sourceMappingURL=securityPolicyService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"securityPolicyService.d.ts","sourceRoot":"","sources":["../../src/auth/securityPolicyService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { listQueryString } from './identityService.js';
2
+ const BASE = '/identity/security-policies';
3
+ /** A server error message (`{ message }`) when it is a plain string. */
4
+ function messageOf(data) {
5
+ if (data !== null && typeof data === 'object') {
6
+ const m = data.message;
7
+ if (typeof m === 'string' && m.length > 0)
8
+ return m;
9
+ }
10
+ return null;
11
+ }
12
+ function fail(r, generic) {
13
+ switch (r.status) {
14
+ case 0:
15
+ return { ok: false, status: 0, error: 'Cannot reach the server. Is it running?' };
16
+ case 401:
17
+ return { ok: false, status: 401, error: 'Not authenticated (no/invalid token).' };
18
+ case 403:
19
+ return {
20
+ ok: false,
21
+ status: 403,
22
+ error: messageOf(r.data) ?? 'You do not have access to do this.',
23
+ };
24
+ case 404:
25
+ return { ok: false, status: 404, error: 'Security policy not found.' };
26
+ case 400:
27
+ case 409:
28
+ return { ok: false, status: r.status, error: messageOf(r.data) ?? generic };
29
+ case 503:
30
+ return {
31
+ ok: false,
32
+ status: 503,
33
+ error: 'The service is temporarily unavailable. Please try again shortly.',
34
+ };
35
+ default:
36
+ return { ok: false, status: r.status, error: generic };
37
+ }
38
+ }
39
+ /** Only the documented create fields, each only when set. */
40
+ function createBody(body) {
41
+ return {
42
+ ...(body.scopeNodeUuid !== undefined ? { scopeNodeUuid: body.scopeNodeUuid } : {}),
43
+ ...(body.platform !== undefined ? { platform: body.platform } : {}),
44
+ targetKind: body.targetKind,
45
+ ...(body.targetValue !== undefined ? { targetValue: body.targetValue } : {}),
46
+ ...(body.graceDays !== undefined ? { graceDays: body.graceDays } : {}),
47
+ };
48
+ }
49
+ export function createSecurityPolicyService(http) {
50
+ return {
51
+ /** List the policies the caller may see (their subtree; platform rows for root only). */
52
+ async list(accessToken, opts) {
53
+ const r = await http.get(`${BASE}${listQueryString(opts)}`, {
54
+ bearerToken: accessToken,
55
+ ...(opts?.signal ? { signal: opts.signal } : {}),
56
+ });
57
+ if (r.ok) {
58
+ const data = r.data;
59
+ return {
60
+ ok: true,
61
+ total: data?.total ?? 0,
62
+ rows: data?.rows ?? [],
63
+ page: data?.page ?? 1,
64
+ limit: data?.limit ?? data?.rows?.length ?? 0,
65
+ };
66
+ }
67
+ return fail(r, 'Could not load security policies.');
68
+ },
69
+ /** Read one policy; `policy: null` when it does not exist or is outside the caller's scope. */
70
+ async get(accessToken, uuid) {
71
+ const r = await http.get(`${BASE}/${encodeURIComponent(uuid)}`, {
72
+ bearerToken: accessToken,
73
+ });
74
+ if (r.ok)
75
+ return { ok: true, policy: r.data ?? null };
76
+ return fail(r, 'Could not load the security policy.');
77
+ },
78
+ /** Create a policy → `{ ok:true, id }`. */
79
+ async create(accessToken, body) {
80
+ const r = await http.post(BASE, createBody(body), { bearerToken: accessToken });
81
+ if (r.ok)
82
+ return { ok: true, id: r.data?.id };
83
+ return fail(r, 'Could not create the security policy.');
84
+ },
85
+ /** Change a policy's target value and/or grace period. */
86
+ async update(accessToken, uuid, body) {
87
+ const r = await http.put(`${BASE}/${encodeURIComponent(uuid)}`, {
88
+ ...(body.targetValue !== undefined ? { targetValue: body.targetValue } : {}),
89
+ ...(body.graceDays !== undefined ? { graceDays: body.graceDays } : {}),
90
+ }, { bearerToken: accessToken });
91
+ if (r.ok)
92
+ return { ok: true };
93
+ return fail(r, 'Could not update the security policy.');
94
+ },
95
+ /** Delete a policy. */
96
+ async remove(accessToken, uuid) {
97
+ const r = await http.delete(`${BASE}/${encodeURIComponent(uuid)}`, {}, { bearerToken: accessToken });
98
+ if (r.ok)
99
+ return { ok: true };
100
+ return fail(r, 'Could not delete the policy.');
101
+ },
102
+ };
103
+ }
104
+ //# sourceMappingURL=securityPolicyService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"securityPolicyService.js","sourceRoot":"","sources":["../../src/auth/securityPolicyService.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astram/frontend-core",
3
- "version": "0.6.1",
3
+ "version": "0.8.0",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -24,6 +24,11 @@
24
24
  "typescript": "^5.7.0",
25
25
  "vitest": "^2.1.0"
26
26
  },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/ASTRAM-2-0/astram-framework.git",
30
+ "directory": "packages/frontend-core"
31
+ },
27
32
  "scripts": {
28
33
  "build": "tsc -p tsconfig.json",
29
34
  "lint": "eslint .",