@iveri/contracts 0.1.0 → 0.2.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/README.md +14 -2
- package/dist/cjs/enum/index.d.ts +1 -0
- package/dist/cjs/enum/index.d.ts.map +1 -1
- package/dist/cjs/enum/index.js +1 -0
- package/dist/cjs/enum/index.js.map +1 -1
- package/dist/cjs/enum/user-permission.enum.d.ts +72 -0
- package/dist/cjs/enum/user-permission.enum.d.ts.map +1 -0
- package/dist/cjs/enum/user-permission.enum.js +87 -0
- package/dist/cjs/enum/user-permission.enum.js.map +1 -0
- package/dist/esm/enum/index.d.ts +1 -0
- package/dist/esm/enum/index.d.ts.map +1 -1
- package/dist/esm/enum/index.js +1 -0
- package/dist/esm/enum/index.js.map +1 -1
- package/dist/esm/enum/user-permission.enum.d.ts +72 -0
- package/dist/esm/enum/user-permission.enum.d.ts.map +1 -0
- package/dist/esm/enum/user-permission.enum.js +84 -0
- package/dist/esm/enum/user-permission.enum.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,6 +44,17 @@ Anything needing a dependency belongs in `@iveri/nest-sdk` (backend) or `@iveri/
|
|
|
44
44
|
`ErrorCode` — the stable, machine-readable error classification carried in every error
|
|
45
45
|
response. Clients branch on `code`; `message` is for humans and may change at any time.
|
|
46
46
|
|
|
47
|
+
`UserPermission` + `ALL_USER_PERMISSIONS` — **one catalogue of permissions for the whole
|
|
48
|
+
platform**, not one per service. `iveri-identity-api` stores members on role rows, resolves
|
|
49
|
+
them into access tokens and validates custom-role input against `ALL_USER_PERMISSIONS`; every
|
|
50
|
+
other service reads them back out of the token to authorize a request; the frontend's
|
|
51
|
+
`<RequirePermission>` branches on the same values. A service defining its own enum locally
|
|
52
|
+
would find its permissions unassignable, because identity would reject them as unknown.
|
|
53
|
+
|
|
54
|
+
Values are `<resource>:<action>`, or `<service>:<resource>:<action>` where a resource name
|
|
55
|
+
would otherwise collide — identity's members are unprefixed because they predate the shared
|
|
56
|
+
catalogue and are already embedded in issued tokens and stored role rows.
|
|
57
|
+
|
|
47
58
|
## What is deliberately **not** here yet
|
|
48
59
|
|
|
49
60
|
`event/` (domain event envelope, topics) and `api/` (per-service request/response shapes) are
|
|
@@ -52,8 +63,9 @@ needs them, per the second-consumer rule — not in anticipation.
|
|
|
52
63
|
|
|
53
64
|
## Adding to the contract
|
|
54
65
|
|
|
55
|
-
- A new `ErrorCode` member is a **minor** version. Changing what an
|
|
56
|
-
removing one, is **major** — clients branch on these
|
|
66
|
+
- A new `ErrorCode` or `UserPermission` member is a **minor** version. Changing what an
|
|
67
|
+
existing member means, or removing one, is **major** — clients branch on these, and a
|
|
68
|
+
removed permission silently downgrades every live session whose token still carries it.
|
|
57
69
|
- Widening a type is minor; narrowing it is major.
|
|
58
70
|
- Breaking changes get a migration note in `CHANGELOG.md`. Services upgrade deliberately.
|
|
59
71
|
|
package/dist/cjs/enum/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enum/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enum/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC"}
|
package/dist/cjs/enum/index.js
CHANGED
|
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./error-code.enum.js"), exports);
|
|
18
|
+
__exportStar(require("./user-permission.enum.js"), exports);
|
|
18
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/enum/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/enum/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,4DAA0C"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every action a principal can be granted in an Iveri tenant, across every service.
|
|
3
|
+
*
|
|
4
|
+
* A permission is a **contract**, not an implementation detail: `iveri-identity-api` stores
|
|
5
|
+
* members on role rows and resolves them into access tokens, every other service reads them
|
|
6
|
+
* out of that token to authorize a request, and the frontend's `<RequirePermission>` branches
|
|
7
|
+
* on the same values. A member's wire value therefore never changes, and a member is never
|
|
8
|
+
* removed while issued tokens can still carry it — removing one silently downgrades every
|
|
9
|
+
* live session holding it. Adding one is a minor version.
|
|
10
|
+
*
|
|
11
|
+
* **One catalogue for the whole platform, deliberately.** Identity validates custom-role input
|
|
12
|
+
* against this list, so a permission it has never heard of cannot be granted. A service that
|
|
13
|
+
* defined its own enum locally would find its permissions unassignable.
|
|
14
|
+
*
|
|
15
|
+
* Values are `<resource>:<action>` — or `<service>:<resource>:<action>` where a resource name
|
|
16
|
+
* would otherwise collide across services — lowercase, so a token payload is readable in a
|
|
17
|
+
* log and a wildcard match (`role:*`) stays possible if we ever need one.
|
|
18
|
+
*/
|
|
19
|
+
export declare enum UserPermission {
|
|
20
|
+
TENANT_READ = "tenant:read",
|
|
21
|
+
TENANT_UPDATE = "tenant:update",
|
|
22
|
+
/** Schedules the tenant for deletion. Owner-only; there is no undo path built yet. */
|
|
23
|
+
TENANT_DELETE = "tenant:delete",
|
|
24
|
+
USER_READ = "user:read",
|
|
25
|
+
USER_INVITE = "user:invite",
|
|
26
|
+
USER_UPDATE = "user:update",
|
|
27
|
+
USER_REMOVE = "user:remove",
|
|
28
|
+
MEMBERSHIP_READ = "membership:read",
|
|
29
|
+
/** Suspend or reactivate someone's access without deleting their account. */
|
|
30
|
+
MEMBERSHIP_UPDATE = "membership:update",
|
|
31
|
+
/**
|
|
32
|
+
* Change which roles a membership holds. Separate from `MEMBERSHIP_UPDATE` because
|
|
33
|
+
* granting roles is privilege escalation and deserves its own gate.
|
|
34
|
+
*/
|
|
35
|
+
MEMBERSHIP_ASSIGN_ROLE = "membership:assign-role",
|
|
36
|
+
ROLE_READ = "role:read",
|
|
37
|
+
ROLE_CREATE = "role:create",
|
|
38
|
+
ROLE_UPDATE = "role:update",
|
|
39
|
+
ROLE_DELETE = "role:delete",
|
|
40
|
+
API_KEY_READ = "api-key:read",
|
|
41
|
+
API_KEY_ISSUE = "api-key:issue",
|
|
42
|
+
API_KEY_REVOKE = "api-key:revoke",
|
|
43
|
+
/** Read endpoint configuration. Never exposes the signing secret. */
|
|
44
|
+
CONDUIT_ENDPOINT_READ = "conduit:endpoint:read",
|
|
45
|
+
CONDUIT_ENDPOINT_CREATE = "conduit:endpoint:create",
|
|
46
|
+
CONDUIT_ENDPOINT_UPDATE = "conduit:endpoint:update",
|
|
47
|
+
CONDUIT_ENDPOINT_DELETE = "conduit:endpoint:delete",
|
|
48
|
+
/**
|
|
49
|
+
* List and read captured requests, **including their raw bodies and headers**. Captures
|
|
50
|
+
* hold whatever a provider sent — order details, message contents, personal data — so
|
|
51
|
+
* this is closer to a data-export permission than a config one.
|
|
52
|
+
*/
|
|
53
|
+
CONDUIT_CAPTURE_READ = "conduit:capture:read",
|
|
54
|
+
CONDUIT_CAPTURE_DELETE = "conduit:capture:delete",
|
|
55
|
+
/**
|
|
56
|
+
* Resend a captured request to an arbitrary URL. Separate from `CONDUIT_CAPTURE_READ`
|
|
57
|
+
* because it makes an outbound request from our infrastructure with a body the caller
|
|
58
|
+
* controls, which is a materially different power from reading a row.
|
|
59
|
+
*/
|
|
60
|
+
CONDUIT_REPLAY_EXECUTE = "conduit:replay:execute",
|
|
61
|
+
CONDUIT_PROVIDER_READ = "conduit:provider:read",
|
|
62
|
+
/** Define or amend a custom provider manifest — signature scheme, headers, handshake. */
|
|
63
|
+
CONDUIT_PROVIDER_MANAGE = "conduit:provider:manage"
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Every member, for seeding the owner role and validating custom-role input.
|
|
67
|
+
*
|
|
68
|
+
* Frozen because it is shared mutable state in a browser bundle otherwise: one caller sorting
|
|
69
|
+
* it in place reorders it for everyone.
|
|
70
|
+
*/
|
|
71
|
+
export declare const ALL_USER_PERMISSIONS: readonly UserPermission[];
|
|
72
|
+
//# sourceMappingURL=user-permission.enum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-permission.enum.d.ts","sourceRoot":"","sources":["../../../src/enum/user-permission.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,oBAAY,cAAc;IAItB,WAAW,gBAAgB;IAC3B,aAAa,kBAAkB;IAC/B,sFAAsF;IACtF,aAAa,kBAAkB;IAG/B,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAG3B,eAAe,oBAAoB;IACnC,6EAA6E;IAC7E,iBAAiB,sBAAsB;IACvC;;;OAGG;IACH,sBAAsB,2BAA2B;IAGjD,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAG3B,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IAKjC,qEAAqE;IACrE,qBAAqB,0BAA0B;IAC/C,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;IAGnD;;;;OAIG;IACH,oBAAoB,yBAAyB;IAC7C,sBAAsB,2BAA2B;IAGjD;;;;OAIG;IACH,sBAAsB,2BAA2B;IAGjD,qBAAqB,0BAA0B;IAC/C,yFAAyF;IACzF,uBAAuB,4BAA4B;CACtD;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,cAAc,EAAiD,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ALL_USER_PERMISSIONS = exports.UserPermission = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Every action a principal can be granted in an Iveri tenant, across every service.
|
|
6
|
+
*
|
|
7
|
+
* A permission is a **contract**, not an implementation detail: `iveri-identity-api` stores
|
|
8
|
+
* members on role rows and resolves them into access tokens, every other service reads them
|
|
9
|
+
* out of that token to authorize a request, and the frontend's `<RequirePermission>` branches
|
|
10
|
+
* on the same values. A member's wire value therefore never changes, and a member is never
|
|
11
|
+
* removed while issued tokens can still carry it — removing one silently downgrades every
|
|
12
|
+
* live session holding it. Adding one is a minor version.
|
|
13
|
+
*
|
|
14
|
+
* **One catalogue for the whole platform, deliberately.** Identity validates custom-role input
|
|
15
|
+
* against this list, so a permission it has never heard of cannot be granted. A service that
|
|
16
|
+
* defined its own enum locally would find its permissions unassignable.
|
|
17
|
+
*
|
|
18
|
+
* Values are `<resource>:<action>` — or `<service>:<resource>:<action>` where a resource name
|
|
19
|
+
* would otherwise collide across services — lowercase, so a token payload is readable in a
|
|
20
|
+
* log and a wildcard match (`role:*`) stays possible if we ever need one.
|
|
21
|
+
*/
|
|
22
|
+
var UserPermission;
|
|
23
|
+
(function (UserPermission) {
|
|
24
|
+
// ══ iveri-identity-api ═══════════════════════════════════════════════════
|
|
25
|
+
// ── Tenant ──────────────────────────────────────────────────────────────
|
|
26
|
+
UserPermission["TENANT_READ"] = "tenant:read";
|
|
27
|
+
UserPermission["TENANT_UPDATE"] = "tenant:update";
|
|
28
|
+
/** Schedules the tenant for deletion. Owner-only; there is no undo path built yet. */
|
|
29
|
+
UserPermission["TENANT_DELETE"] = "tenant:delete";
|
|
30
|
+
// ── User ────────────────────────────────────────────────────────────────
|
|
31
|
+
UserPermission["USER_READ"] = "user:read";
|
|
32
|
+
UserPermission["USER_INVITE"] = "user:invite";
|
|
33
|
+
UserPermission["USER_UPDATE"] = "user:update";
|
|
34
|
+
UserPermission["USER_REMOVE"] = "user:remove";
|
|
35
|
+
// ── Membership ──────────────────────────────────────────────────────────
|
|
36
|
+
UserPermission["MEMBERSHIP_READ"] = "membership:read";
|
|
37
|
+
/** Suspend or reactivate someone's access without deleting their account. */
|
|
38
|
+
UserPermission["MEMBERSHIP_UPDATE"] = "membership:update";
|
|
39
|
+
/**
|
|
40
|
+
* Change which roles a membership holds. Separate from `MEMBERSHIP_UPDATE` because
|
|
41
|
+
* granting roles is privilege escalation and deserves its own gate.
|
|
42
|
+
*/
|
|
43
|
+
UserPermission["MEMBERSHIP_ASSIGN_ROLE"] = "membership:assign-role";
|
|
44
|
+
// ── Role ────────────────────────────────────────────────────────────────
|
|
45
|
+
UserPermission["ROLE_READ"] = "role:read";
|
|
46
|
+
UserPermission["ROLE_CREATE"] = "role:create";
|
|
47
|
+
UserPermission["ROLE_UPDATE"] = "role:update";
|
|
48
|
+
UserPermission["ROLE_DELETE"] = "role:delete";
|
|
49
|
+
// ── API key ─────────────────────────────────────────────────────────────
|
|
50
|
+
UserPermission["API_KEY_READ"] = "api-key:read";
|
|
51
|
+
UserPermission["API_KEY_ISSUE"] = "api-key:issue";
|
|
52
|
+
UserPermission["API_KEY_REVOKE"] = "api-key:revoke";
|
|
53
|
+
// ══ conduit-api ══════════════════════════════════════════════════════════
|
|
54
|
+
// ── Endpoint ────────────────────────────────────────────────────────────
|
|
55
|
+
/** Read endpoint configuration. Never exposes the signing secret. */
|
|
56
|
+
UserPermission["CONDUIT_ENDPOINT_READ"] = "conduit:endpoint:read";
|
|
57
|
+
UserPermission["CONDUIT_ENDPOINT_CREATE"] = "conduit:endpoint:create";
|
|
58
|
+
UserPermission["CONDUIT_ENDPOINT_UPDATE"] = "conduit:endpoint:update";
|
|
59
|
+
UserPermission["CONDUIT_ENDPOINT_DELETE"] = "conduit:endpoint:delete";
|
|
60
|
+
// ── Capture ─────────────────────────────────────────────────────────────
|
|
61
|
+
/**
|
|
62
|
+
* List and read captured requests, **including their raw bodies and headers**. Captures
|
|
63
|
+
* hold whatever a provider sent — order details, message contents, personal data — so
|
|
64
|
+
* this is closer to a data-export permission than a config one.
|
|
65
|
+
*/
|
|
66
|
+
UserPermission["CONDUIT_CAPTURE_READ"] = "conduit:capture:read";
|
|
67
|
+
UserPermission["CONDUIT_CAPTURE_DELETE"] = "conduit:capture:delete";
|
|
68
|
+
// ── Replay ──────────────────────────────────────────────────────────────
|
|
69
|
+
/**
|
|
70
|
+
* Resend a captured request to an arbitrary URL. Separate from `CONDUIT_CAPTURE_READ`
|
|
71
|
+
* because it makes an outbound request from our infrastructure with a body the caller
|
|
72
|
+
* controls, which is a materially different power from reading a row.
|
|
73
|
+
*/
|
|
74
|
+
UserPermission["CONDUIT_REPLAY_EXECUTE"] = "conduit:replay:execute";
|
|
75
|
+
// ── Provider ────────────────────────────────────────────────────────────
|
|
76
|
+
UserPermission["CONDUIT_PROVIDER_READ"] = "conduit:provider:read";
|
|
77
|
+
/** Define or amend a custom provider manifest — signature scheme, headers, handshake. */
|
|
78
|
+
UserPermission["CONDUIT_PROVIDER_MANAGE"] = "conduit:provider:manage";
|
|
79
|
+
})(UserPermission || (exports.UserPermission = UserPermission = {}));
|
|
80
|
+
/**
|
|
81
|
+
* Every member, for seeding the owner role and validating custom-role input.
|
|
82
|
+
*
|
|
83
|
+
* Frozen because it is shared mutable state in a browser bundle otherwise: one caller sorting
|
|
84
|
+
* it in place reorders it for everyone.
|
|
85
|
+
*/
|
|
86
|
+
exports.ALL_USER_PERMISSIONS = Object.freeze(Object.values(UserPermission));
|
|
87
|
+
//# sourceMappingURL=user-permission.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-permission.enum.js","sourceRoot":"","sources":["../../../src/enum/user-permission.enum.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,IAAY,cAkEX;AAlED,WAAY,cAAc;IACtB,4EAA4E;IAE5E,2EAA2E;IAC3E,6CAA2B,CAAA;IAC3B,iDAA+B,CAAA;IAC/B,sFAAsF;IACtF,iDAA+B,CAAA;IAE/B,2EAA2E;IAC3E,yCAAuB,CAAA;IACvB,6CAA2B,CAAA;IAC3B,6CAA2B,CAAA;IAC3B,6CAA2B,CAAA;IAE3B,2EAA2E;IAC3E,qDAAmC,CAAA;IACnC,6EAA6E;IAC7E,yDAAuC,CAAA;IACvC;;;OAGG;IACH,mEAAiD,CAAA;IAEjD,2EAA2E;IAC3E,yCAAuB,CAAA;IACvB,6CAA2B,CAAA;IAC3B,6CAA2B,CAAA;IAC3B,6CAA2B,CAAA;IAE3B,2EAA2E;IAC3E,+CAA6B,CAAA;IAC7B,iDAA+B,CAAA;IAC/B,mDAAiC,CAAA;IAEjC,4EAA4E;IAE5E,2EAA2E;IAC3E,qEAAqE;IACrE,iEAA+C,CAAA;IAC/C,qEAAmD,CAAA;IACnD,qEAAmD,CAAA;IACnD,qEAAmD,CAAA;IAEnD,2EAA2E;IAC3E;;;;OAIG;IACH,+DAA6C,CAAA;IAC7C,mEAAiD,CAAA;IAEjD,2EAA2E;IAC3E;;;;OAIG;IACH,mEAAiD,CAAA;IAEjD,2EAA2E;IAC3E,iEAA+C,CAAA;IAC/C,yFAAyF;IACzF,qEAAmD,CAAA;AACvD,CAAC,EAlEW,cAAc,8BAAd,cAAc,QAkEzB;AAED;;;;;GAKG;AACU,QAAA,oBAAoB,GAA8B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC"}
|
package/dist/esm/enum/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enum/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enum/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC"}
|
package/dist/esm/enum/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/enum/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/enum/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every action a principal can be granted in an Iveri tenant, across every service.
|
|
3
|
+
*
|
|
4
|
+
* A permission is a **contract**, not an implementation detail: `iveri-identity-api` stores
|
|
5
|
+
* members on role rows and resolves them into access tokens, every other service reads them
|
|
6
|
+
* out of that token to authorize a request, and the frontend's `<RequirePermission>` branches
|
|
7
|
+
* on the same values. A member's wire value therefore never changes, and a member is never
|
|
8
|
+
* removed while issued tokens can still carry it — removing one silently downgrades every
|
|
9
|
+
* live session holding it. Adding one is a minor version.
|
|
10
|
+
*
|
|
11
|
+
* **One catalogue for the whole platform, deliberately.** Identity validates custom-role input
|
|
12
|
+
* against this list, so a permission it has never heard of cannot be granted. A service that
|
|
13
|
+
* defined its own enum locally would find its permissions unassignable.
|
|
14
|
+
*
|
|
15
|
+
* Values are `<resource>:<action>` — or `<service>:<resource>:<action>` where a resource name
|
|
16
|
+
* would otherwise collide across services — lowercase, so a token payload is readable in a
|
|
17
|
+
* log and a wildcard match (`role:*`) stays possible if we ever need one.
|
|
18
|
+
*/
|
|
19
|
+
export declare enum UserPermission {
|
|
20
|
+
TENANT_READ = "tenant:read",
|
|
21
|
+
TENANT_UPDATE = "tenant:update",
|
|
22
|
+
/** Schedules the tenant for deletion. Owner-only; there is no undo path built yet. */
|
|
23
|
+
TENANT_DELETE = "tenant:delete",
|
|
24
|
+
USER_READ = "user:read",
|
|
25
|
+
USER_INVITE = "user:invite",
|
|
26
|
+
USER_UPDATE = "user:update",
|
|
27
|
+
USER_REMOVE = "user:remove",
|
|
28
|
+
MEMBERSHIP_READ = "membership:read",
|
|
29
|
+
/** Suspend or reactivate someone's access without deleting their account. */
|
|
30
|
+
MEMBERSHIP_UPDATE = "membership:update",
|
|
31
|
+
/**
|
|
32
|
+
* Change which roles a membership holds. Separate from `MEMBERSHIP_UPDATE` because
|
|
33
|
+
* granting roles is privilege escalation and deserves its own gate.
|
|
34
|
+
*/
|
|
35
|
+
MEMBERSHIP_ASSIGN_ROLE = "membership:assign-role",
|
|
36
|
+
ROLE_READ = "role:read",
|
|
37
|
+
ROLE_CREATE = "role:create",
|
|
38
|
+
ROLE_UPDATE = "role:update",
|
|
39
|
+
ROLE_DELETE = "role:delete",
|
|
40
|
+
API_KEY_READ = "api-key:read",
|
|
41
|
+
API_KEY_ISSUE = "api-key:issue",
|
|
42
|
+
API_KEY_REVOKE = "api-key:revoke",
|
|
43
|
+
/** Read endpoint configuration. Never exposes the signing secret. */
|
|
44
|
+
CONDUIT_ENDPOINT_READ = "conduit:endpoint:read",
|
|
45
|
+
CONDUIT_ENDPOINT_CREATE = "conduit:endpoint:create",
|
|
46
|
+
CONDUIT_ENDPOINT_UPDATE = "conduit:endpoint:update",
|
|
47
|
+
CONDUIT_ENDPOINT_DELETE = "conduit:endpoint:delete",
|
|
48
|
+
/**
|
|
49
|
+
* List and read captured requests, **including their raw bodies and headers**. Captures
|
|
50
|
+
* hold whatever a provider sent — order details, message contents, personal data — so
|
|
51
|
+
* this is closer to a data-export permission than a config one.
|
|
52
|
+
*/
|
|
53
|
+
CONDUIT_CAPTURE_READ = "conduit:capture:read",
|
|
54
|
+
CONDUIT_CAPTURE_DELETE = "conduit:capture:delete",
|
|
55
|
+
/**
|
|
56
|
+
* Resend a captured request to an arbitrary URL. Separate from `CONDUIT_CAPTURE_READ`
|
|
57
|
+
* because it makes an outbound request from our infrastructure with a body the caller
|
|
58
|
+
* controls, which is a materially different power from reading a row.
|
|
59
|
+
*/
|
|
60
|
+
CONDUIT_REPLAY_EXECUTE = "conduit:replay:execute",
|
|
61
|
+
CONDUIT_PROVIDER_READ = "conduit:provider:read",
|
|
62
|
+
/** Define or amend a custom provider manifest — signature scheme, headers, handshake. */
|
|
63
|
+
CONDUIT_PROVIDER_MANAGE = "conduit:provider:manage"
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Every member, for seeding the owner role and validating custom-role input.
|
|
67
|
+
*
|
|
68
|
+
* Frozen because it is shared mutable state in a browser bundle otherwise: one caller sorting
|
|
69
|
+
* it in place reorders it for everyone.
|
|
70
|
+
*/
|
|
71
|
+
export declare const ALL_USER_PERMISSIONS: readonly UserPermission[];
|
|
72
|
+
//# sourceMappingURL=user-permission.enum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-permission.enum.d.ts","sourceRoot":"","sources":["../../../src/enum/user-permission.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,oBAAY,cAAc;IAItB,WAAW,gBAAgB;IAC3B,aAAa,kBAAkB;IAC/B,sFAAsF;IACtF,aAAa,kBAAkB;IAG/B,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAG3B,eAAe,oBAAoB;IACnC,6EAA6E;IAC7E,iBAAiB,sBAAsB;IACvC;;;OAGG;IACH,sBAAsB,2BAA2B;IAGjD,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAG3B,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IAKjC,qEAAqE;IACrE,qBAAqB,0BAA0B;IAC/C,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;IAGnD;;;;OAIG;IACH,oBAAoB,yBAAyB;IAC7C,sBAAsB,2BAA2B;IAGjD;;;;OAIG;IACH,sBAAsB,2BAA2B;IAGjD,qBAAqB,0BAA0B;IAC/C,yFAAyF;IACzF,uBAAuB,4BAA4B;CACtD;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,cAAc,EAAiD,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every action a principal can be granted in an Iveri tenant, across every service.
|
|
3
|
+
*
|
|
4
|
+
* A permission is a **contract**, not an implementation detail: `iveri-identity-api` stores
|
|
5
|
+
* members on role rows and resolves them into access tokens, every other service reads them
|
|
6
|
+
* out of that token to authorize a request, and the frontend's `<RequirePermission>` branches
|
|
7
|
+
* on the same values. A member's wire value therefore never changes, and a member is never
|
|
8
|
+
* removed while issued tokens can still carry it — removing one silently downgrades every
|
|
9
|
+
* live session holding it. Adding one is a minor version.
|
|
10
|
+
*
|
|
11
|
+
* **One catalogue for the whole platform, deliberately.** Identity validates custom-role input
|
|
12
|
+
* against this list, so a permission it has never heard of cannot be granted. A service that
|
|
13
|
+
* defined its own enum locally would find its permissions unassignable.
|
|
14
|
+
*
|
|
15
|
+
* Values are `<resource>:<action>` — or `<service>:<resource>:<action>` where a resource name
|
|
16
|
+
* would otherwise collide across services — lowercase, so a token payload is readable in a
|
|
17
|
+
* log and a wildcard match (`role:*`) stays possible if we ever need one.
|
|
18
|
+
*/
|
|
19
|
+
export var UserPermission;
|
|
20
|
+
(function (UserPermission) {
|
|
21
|
+
// ══ iveri-identity-api ═══════════════════════════════════════════════════
|
|
22
|
+
// ── Tenant ──────────────────────────────────────────────────────────────
|
|
23
|
+
UserPermission["TENANT_READ"] = "tenant:read";
|
|
24
|
+
UserPermission["TENANT_UPDATE"] = "tenant:update";
|
|
25
|
+
/** Schedules the tenant for deletion. Owner-only; there is no undo path built yet. */
|
|
26
|
+
UserPermission["TENANT_DELETE"] = "tenant:delete";
|
|
27
|
+
// ── User ────────────────────────────────────────────────────────────────
|
|
28
|
+
UserPermission["USER_READ"] = "user:read";
|
|
29
|
+
UserPermission["USER_INVITE"] = "user:invite";
|
|
30
|
+
UserPermission["USER_UPDATE"] = "user:update";
|
|
31
|
+
UserPermission["USER_REMOVE"] = "user:remove";
|
|
32
|
+
// ── Membership ──────────────────────────────────────────────────────────
|
|
33
|
+
UserPermission["MEMBERSHIP_READ"] = "membership:read";
|
|
34
|
+
/** Suspend or reactivate someone's access without deleting their account. */
|
|
35
|
+
UserPermission["MEMBERSHIP_UPDATE"] = "membership:update";
|
|
36
|
+
/**
|
|
37
|
+
* Change which roles a membership holds. Separate from `MEMBERSHIP_UPDATE` because
|
|
38
|
+
* granting roles is privilege escalation and deserves its own gate.
|
|
39
|
+
*/
|
|
40
|
+
UserPermission["MEMBERSHIP_ASSIGN_ROLE"] = "membership:assign-role";
|
|
41
|
+
// ── Role ────────────────────────────────────────────────────────────────
|
|
42
|
+
UserPermission["ROLE_READ"] = "role:read";
|
|
43
|
+
UserPermission["ROLE_CREATE"] = "role:create";
|
|
44
|
+
UserPermission["ROLE_UPDATE"] = "role:update";
|
|
45
|
+
UserPermission["ROLE_DELETE"] = "role:delete";
|
|
46
|
+
// ── API key ─────────────────────────────────────────────────────────────
|
|
47
|
+
UserPermission["API_KEY_READ"] = "api-key:read";
|
|
48
|
+
UserPermission["API_KEY_ISSUE"] = "api-key:issue";
|
|
49
|
+
UserPermission["API_KEY_REVOKE"] = "api-key:revoke";
|
|
50
|
+
// ══ conduit-api ══════════════════════════════════════════════════════════
|
|
51
|
+
// ── Endpoint ────────────────────────────────────────────────────────────
|
|
52
|
+
/** Read endpoint configuration. Never exposes the signing secret. */
|
|
53
|
+
UserPermission["CONDUIT_ENDPOINT_READ"] = "conduit:endpoint:read";
|
|
54
|
+
UserPermission["CONDUIT_ENDPOINT_CREATE"] = "conduit:endpoint:create";
|
|
55
|
+
UserPermission["CONDUIT_ENDPOINT_UPDATE"] = "conduit:endpoint:update";
|
|
56
|
+
UserPermission["CONDUIT_ENDPOINT_DELETE"] = "conduit:endpoint:delete";
|
|
57
|
+
// ── Capture ─────────────────────────────────────────────────────────────
|
|
58
|
+
/**
|
|
59
|
+
* List and read captured requests, **including their raw bodies and headers**. Captures
|
|
60
|
+
* hold whatever a provider sent — order details, message contents, personal data — so
|
|
61
|
+
* this is closer to a data-export permission than a config one.
|
|
62
|
+
*/
|
|
63
|
+
UserPermission["CONDUIT_CAPTURE_READ"] = "conduit:capture:read";
|
|
64
|
+
UserPermission["CONDUIT_CAPTURE_DELETE"] = "conduit:capture:delete";
|
|
65
|
+
// ── Replay ──────────────────────────────────────────────────────────────
|
|
66
|
+
/**
|
|
67
|
+
* Resend a captured request to an arbitrary URL. Separate from `CONDUIT_CAPTURE_READ`
|
|
68
|
+
* because it makes an outbound request from our infrastructure with a body the caller
|
|
69
|
+
* controls, which is a materially different power from reading a row.
|
|
70
|
+
*/
|
|
71
|
+
UserPermission["CONDUIT_REPLAY_EXECUTE"] = "conduit:replay:execute";
|
|
72
|
+
// ── Provider ────────────────────────────────────────────────────────────
|
|
73
|
+
UserPermission["CONDUIT_PROVIDER_READ"] = "conduit:provider:read";
|
|
74
|
+
/** Define or amend a custom provider manifest — signature scheme, headers, handshake. */
|
|
75
|
+
UserPermission["CONDUIT_PROVIDER_MANAGE"] = "conduit:provider:manage";
|
|
76
|
+
})(UserPermission || (UserPermission = {}));
|
|
77
|
+
/**
|
|
78
|
+
* Every member, for seeding the owner role and validating custom-role input.
|
|
79
|
+
*
|
|
80
|
+
* Frozen because it is shared mutable state in a browser bundle otherwise: one caller sorting
|
|
81
|
+
* it in place reorders it for everyone.
|
|
82
|
+
*/
|
|
83
|
+
export const ALL_USER_PERMISSIONS = Object.freeze(Object.values(UserPermission));
|
|
84
|
+
//# sourceMappingURL=user-permission.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-permission.enum.js","sourceRoot":"","sources":["../../../src/enum/user-permission.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAN,IAAY,cAkEX;AAlED,WAAY,cAAc;IACtB,4EAA4E;IAE5E,2EAA2E;IAC3E,6CAA2B,CAAA;IAC3B,iDAA+B,CAAA;IAC/B,sFAAsF;IACtF,iDAA+B,CAAA;IAE/B,2EAA2E;IAC3E,yCAAuB,CAAA;IACvB,6CAA2B,CAAA;IAC3B,6CAA2B,CAAA;IAC3B,6CAA2B,CAAA;IAE3B,2EAA2E;IAC3E,qDAAmC,CAAA;IACnC,6EAA6E;IAC7E,yDAAuC,CAAA;IACvC;;;OAGG;IACH,mEAAiD,CAAA;IAEjD,2EAA2E;IAC3E,yCAAuB,CAAA;IACvB,6CAA2B,CAAA;IAC3B,6CAA2B,CAAA;IAC3B,6CAA2B,CAAA;IAE3B,2EAA2E;IAC3E,+CAA6B,CAAA;IAC7B,iDAA+B,CAAA;IAC/B,mDAAiC,CAAA;IAEjC,4EAA4E;IAE5E,2EAA2E;IAC3E,qEAAqE;IACrE,iEAA+C,CAAA;IAC/C,qEAAmD,CAAA;IACnD,qEAAmD,CAAA;IACnD,qEAAmD,CAAA;IAEnD,2EAA2E;IAC3E;;;;OAIG;IACH,+DAA6C,CAAA;IAC7C,mEAAiD,CAAA;IAEjD,2EAA2E;IAC3E;;;;OAIG;IACH,mEAAiD,CAAA;IAEjD,2EAA2E;IAC3E,iEAA+C,CAAA;IAC/C,yFAAyF;IACzF,qEAAmD,CAAA;AACvD,CAAC,EAlEW,cAAc,KAAd,cAAc,QAkEzB;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA8B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC"}
|