@owlmeans/server-iam 0.1.18-rc.9 → 0.1.18
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 +13 -4
- package/agent-meta/manifest.json +3 -3
- package/agent-meta/skills/server-iam/SKILL.md +142 -16
- package/build/append.d.ts +1 -5
- package/build/append.d.ts.map +1 -1
- package/build/append.js.map +1 -1
- package/build/consts.local.d.ts +3 -0
- package/build/consts.local.d.ts.map +1 -0
- package/build/consts.local.js +3 -0
- package/build/consts.local.js.map +1 -0
- package/build/gate.d.ts +13 -14
- package/build/gate.d.ts.map +1 -1
- package/build/gate.js +128 -35
- package/build/gate.js.map +1 -1
- package/build/index.d.ts +6 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -0
- package/build/index.js.map +1 -1
- package/build/organization/types.d.ts +21 -0
- package/build/organization/types.d.ts.map +1 -0
- package/build/organization/types.js +2 -0
- package/build/organization/types.js.map +1 -0
- package/build/organization.d.ts +9 -0
- package/build/organization.d.ts.map +1 -0
- package/build/organization.js +30 -0
- package/build/organization.js.map +1 -0
- package/build/runtime.d.ts +15 -0
- package/build/runtime.d.ts.map +1 -0
- package/build/runtime.js +167 -0
- package/build/runtime.js.map +1 -0
- package/build/types.d.ts +42 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/types.local.d.ts +16 -0
- package/build/types.local.d.ts.map +1 -0
- package/build/types.local.js +2 -0
- package/build/types.local.js.map +1 -0
- package/package.json +12 -10
- package/src/append.ts +1 -4
- package/src/consts.local.ts +2 -0
- package/src/gate.ts +157 -45
- package/src/index.ts +6 -0
- package/src/organization/types.ts +21 -0
- package/src/organization.ts +49 -0
- package/src/runtime.ts +193 -0
- package/src/types.local.ts +18 -0
- package/src/types.ts +43 -0
- package/tests/context.ts +100 -0
- package/tests/gate.spec.ts +132 -4
- package/tests/organization.spec.ts +52 -0
- package/tests/runtime.spec.ts +169 -0
- package/tests/tsconfig.json +12 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ResolvedEntity } from '@owlmeans/entrypoint';
|
|
2
|
+
import type { OIDCAuthCache } from '@owlmeans/server-oidc-rp';
|
|
3
|
+
/** The organizations of one request's subject, read from its session — built once per handler. */
|
|
4
|
+
export interface OrganizationScope {
|
|
5
|
+
/** The session record behind the request's wrapped token — the guard has already refreshed it. */
|
|
6
|
+
sessionOf: () => Promise<OIDCAuthCache>;
|
|
7
|
+
/**
|
|
8
|
+
* Every organization of the request's subject, as request entities keyed by their frozen IAM key.
|
|
9
|
+
*
|
|
10
|
+
* The session record is the authority — the provider's last claim, re-read on every validation —
|
|
11
|
+
* never the browser: a relying party of a tenanted client has no organization registry of its own.
|
|
12
|
+
*/
|
|
13
|
+
organizationsOf: () => Promise<ResolvedEntity[]>;
|
|
14
|
+
/**
|
|
15
|
+
* One organization of the request's subject by its slug — for a handler that acts in an
|
|
16
|
+
* organization the URL names rather than in the session's acting one. One the subject is not in is
|
|
17
|
+
* refused as `AuthForbidden(ORGANIZATION_REFUSAL)`, exactly as the switch refuses it.
|
|
18
|
+
*/
|
|
19
|
+
organizationOf: (entitySlug: string) => Promise<ResolvedEntity>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/organization/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAE7D,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IAChC,kGAAkG;IAClG,SAAS,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IACvC;;;;;OAKG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC,CAAA;IAChD;;;;OAIG;IACH,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAA;CAChE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/organization/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AbstractRequest, ResolvedEntity } from '@owlmeans/entrypoint';
|
|
2
|
+
import type { Config, Context } from '@owlmeans/server-oidc-rp';
|
|
3
|
+
import type { OrganizationScope } from './organization/types.js';
|
|
4
|
+
export declare const makeOrganizationScope: <C extends Config, T extends Context<C>>(context: T, request: AbstractRequest) => OrganizationScope;
|
|
5
|
+
/** @deprecated compat:factory-refactor — use `makeOrganizationScope(context, request).organizationsOf()` */
|
|
6
|
+
export declare const organizationsOf: <C extends Config, T extends Context<C>>(context: T, request: AbstractRequest) => Promise<ResolvedEntity[]>;
|
|
7
|
+
/** @deprecated compat:factory-refactor — use `makeOrganizationScope(context, request).organizationOf(…)` */
|
|
8
|
+
export declare const organizationOf: <C extends Config, T extends Context<C>>(context: T, request: AbstractRequest, entitySlug: string) => Promise<ResolvedEntity>;
|
|
9
|
+
//# sourceMappingURL=organization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organization.d.ts","sourceRoot":"","sources":["../src/organization.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAI3E,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAiB,MAAM,0BAA0B,CAAA;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAShE,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WACjE,CAAC,WAAW,eAAe,KACnC,iBAqBF,CAAA;AAED,4GAA4G;AAC5G,eAAO,MAAM,eAAe,GAAU,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WACjE,CAAC,WAAW,eAAe,KACnC,OAAO,CAAC,cAAc,EAAE,CAA0E,CAAA;AAErG,4GAA4G;AAC5G,eAAO,MAAM,cAAc,GAAU,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAChE,CAAC,WAAW,eAAe,cAAc,MAAM,KACvD,OAAO,CAAC,cAAc,CAAmF,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AuthForbidden, AuthorizationError } from '@owlmeans/auth';
|
|
2
|
+
import { ORGANIZATION_REFUSAL } from '@owlmeans/oidc';
|
|
3
|
+
import { resolvedEntityOf, sessionRecord } from '@owlmeans/server-oidc-rp';
|
|
4
|
+
/**
|
|
5
|
+
* The organizations the provider last claimed for the session's subject. A session that acts in
|
|
6
|
+
* none — a client without the organizations scope — has none to offer, whatever its record holds.
|
|
7
|
+
*/
|
|
8
|
+
const claimedOf = (record) => record.acting == null ? [] : record.organizations ?? [];
|
|
9
|
+
export const makeOrganizationScope = (context, request) => {
|
|
10
|
+
const sessionOf = async () => {
|
|
11
|
+
if (request.auth == null) {
|
|
12
|
+
throw new AuthorizationError('auth');
|
|
13
|
+
}
|
|
14
|
+
return sessionRecord(context, request.auth.token);
|
|
15
|
+
};
|
|
16
|
+
const organizationsOf = async () => claimedOf(await sessionOf()).map(resolvedEntityOf);
|
|
17
|
+
const organizationOf = async (entitySlug) => {
|
|
18
|
+
const org = claimedOf(await sessionOf()).find(org => org.entitySlug === entitySlug);
|
|
19
|
+
if (org == null) {
|
|
20
|
+
throw new AuthForbidden(ORGANIZATION_REFUSAL);
|
|
21
|
+
}
|
|
22
|
+
return resolvedEntityOf(org);
|
|
23
|
+
};
|
|
24
|
+
return { sessionOf, organizationsOf, organizationOf };
|
|
25
|
+
};
|
|
26
|
+
/** @deprecated compat:factory-refactor — use `makeOrganizationScope(context, request).organizationsOf()` */
|
|
27
|
+
export const organizationsOf = async (context, request) => await makeOrganizationScope(context, request).organizationsOf();
|
|
28
|
+
/** @deprecated compat:factory-refactor — use `makeOrganizationScope(context, request).organizationOf(…)` */
|
|
29
|
+
export const organizationOf = async (context, request, entitySlug) => await makeOrganizationScope(context, request).organizationOf(entitySlug);
|
|
30
|
+
//# sourceMappingURL=organization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organization.js","sourceRoot":"","sources":["../src/organization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAElE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAI1E;;;GAGG;AACH,MAAM,SAAS,GAAG,CAAC,MAAqB,EAA2B,EAAE,CACnE,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAA;AAEzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,OAAU,EAAE,OAAwB,EACjB,EAAE;IACrB,MAAM,SAAS,GAAG,KAAK,IAA4B,EAAE;QACnD,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACzB,MAAM,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAA;QACtC,CAAC;QAED,OAAO,aAAa,CAAO,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACzD,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,KAAK,IAA+B,EAAE,CAAC,SAAS,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;IAEjH,MAAM,cAAc,GAAG,KAAK,EAAE,UAAkB,EAA2B,EAAE;QAC3E,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,UAAU,CAAC,CAAA;QACnF,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,MAAM,IAAI,aAAa,CAAC,oBAAoB,CAAC,CAAA;QAC/C,CAAC;QAED,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC,CAAA;IAED,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,CAAA;AACvD,CAAC,CAAA;AAED,4GAA4G;AAC5G,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,OAAU,EAAE,OAAwB,EACT,EAAE,CAAC,MAAM,qBAAqB,CAAO,OAAO,EAAE,OAAO,CAAC,CAAC,eAAe,EAAE,CAAA;AAErG,4GAA4G;AAC5G,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,OAAU,EAAE,OAAwB,EAAE,UAAkB,EAC/B,EAAE,CAAC,MAAM,qBAAqB,CAAO,OAAO,EAAE,OAAO,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AbstractRequest } from '@owlmeans/entrypoint';
|
|
2
|
+
import { type Config, type Context } from '@owlmeans/server-oidc-rp';
|
|
3
|
+
import type { IamRuntimeClient } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* A typed client of the provider's runtime IAM API, bound to one request.
|
|
6
|
+
*
|
|
7
|
+
* It calls as the request's subject: the bearer is the provider access token of that request's
|
|
8
|
+
* session record, read afresh on every call, so a token the guard has just refreshed is the one
|
|
9
|
+
* sent. The base URL is the provider's discovery field `IAM_API_METADATA`. Calls travel over plain
|
|
10
|
+
* `fetch`, because the API is another service's tree and a relying party binds none of it.
|
|
11
|
+
*/
|
|
12
|
+
export declare const makeIamRuntimeClient: <C extends Config, T extends Context<C>>(context: T, request: AbstractRequest) => IamRuntimeClient;
|
|
13
|
+
/** @deprecated compat:factory-refactor — use `makeIamRuntimeClient(context, request)` */
|
|
14
|
+
export declare const iamRuntime: <C extends Config, T extends Context<C>>(context: T, request: AbstractRequest) => IamRuntimeClient;
|
|
15
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAI3D,OAAO,EAAwC,KAAK,MAAM,EAAE,KAAK,OAAO,EAA0B,MAAM,0BAA0B,CAAA;AAIlI,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAmDlD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAChE,CAAC,WAAW,eAAe,KACnC,gBAqHF,CAAA;AAED,yFAAyF;AACzF,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WACtD,CAAC,WAAW,eAAe,KACnC,gBAAgE,CAAA"}
|
package/build/runtime.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { AuthForbidden, AuthorizationError, AuthUnavailable } from '@owlmeans/auth';
|
|
2
|
+
import { ResilientError } from '@owlmeans/error';
|
|
3
|
+
import { IAM_RUNTIME_ROUTES, IamClientError, IamError } from '@owlmeans/iam';
|
|
4
|
+
import { IAM_API_METADATA, ORGANIZATION_OWNER_REFUSAL, ORGANIZATION_REFUSAL } from '@owlmeans/oidc';
|
|
5
|
+
import { DEFAULT_ALIAS as OIDC_CLIENT_SERVICE } from '@owlmeans/server-oidc-rp';
|
|
6
|
+
import { makeOrganizationScope } from './organization.js';
|
|
7
|
+
import { INCIDENT_ID_HEADER } from './consts.local.js';
|
|
8
|
+
/**
|
|
9
|
+
* Discovered runtime bases, per context and per client. Discovery is a network round trip the OIDC
|
|
10
|
+
* client service does not memoise, and the base never changes while a provider runs. A failed
|
|
11
|
+
* lookup is forgotten, so the next request asks again rather than inheriting the error.
|
|
12
|
+
*/
|
|
13
|
+
const bases = new WeakMap();
|
|
14
|
+
const pathOf = (path, params = {}) => path.replace(/:(\w+)/g, (_, key) => {
|
|
15
|
+
const value = params[key];
|
|
16
|
+
if (value == null || value === '') {
|
|
17
|
+
throw new IamError(`runtime:param:${key}`);
|
|
18
|
+
}
|
|
19
|
+
return encodeURIComponent(value);
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* The error a refused call rejects with.
|
|
23
|
+
*
|
|
24
|
+
* A development server sends the marshalled error, which is rebuilt into its own class. A production
|
|
25
|
+
* one sends only an incident id, so the status and the route's access level are all there is to go
|
|
26
|
+
* on: a 403 from an owner-level route is the subject not owning the organization, from any other
|
|
27
|
+
* route the subject not being in it.
|
|
28
|
+
*/
|
|
29
|
+
const failureOf = async (response, access) => {
|
|
30
|
+
const text = await response.text().catch(() => '');
|
|
31
|
+
const incidentId = response.headers.get(INCIDENT_ID_HEADER) ?? undefined;
|
|
32
|
+
if (text.includes(ResilientError.separator)) {
|
|
33
|
+
try {
|
|
34
|
+
const error = ResilientError.ensure(text, true);
|
|
35
|
+
error.incidentId ??= incidentId;
|
|
36
|
+
return error;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Not a marshalled error after all — fall through to the status.
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const error = response.status === 401 ? new AuthorizationError('iam-runtime')
|
|
43
|
+
: response.status === 403 ? new AuthForbidden(access === 'owner' ? ORGANIZATION_OWNER_REFUSAL : ORGANIZATION_REFUSAL)
|
|
44
|
+
: new IamError(`runtime:status:${response.status}`);
|
|
45
|
+
if (incidentId != null) {
|
|
46
|
+
error.incidentId = incidentId;
|
|
47
|
+
}
|
|
48
|
+
return error;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A typed client of the provider's runtime IAM API, bound to one request.
|
|
52
|
+
*
|
|
53
|
+
* It calls as the request's subject: the bearer is the provider access token of that request's
|
|
54
|
+
* session record, read afresh on every call, so a token the guard has just refreshed is the one
|
|
55
|
+
* sent. The base URL is the provider's discovery field `IAM_API_METADATA`. Calls travel over plain
|
|
56
|
+
* `fetch`, because the API is another service's tree and a relying party binds none of it.
|
|
57
|
+
*/
|
|
58
|
+
export const makeIamRuntimeClient = (context, request) => {
|
|
59
|
+
const runtimeBase = (clientId) => {
|
|
60
|
+
const known = bases.get(context) ?? new Map();
|
|
61
|
+
bases.set(context, known);
|
|
62
|
+
const cached = known.get(clientId);
|
|
63
|
+
if (cached != null) {
|
|
64
|
+
return cached;
|
|
65
|
+
}
|
|
66
|
+
const attempt = (async () => {
|
|
67
|
+
const client = await context.service(OIDC_CLIENT_SERVICE).getClient(clientId);
|
|
68
|
+
const base = client.getMetadata()[IAM_API_METADATA];
|
|
69
|
+
if (typeof base !== 'string' || base === '') {
|
|
70
|
+
// A provider that advertises no runtime API — Keycloak, or an integrated provider that does not
|
|
71
|
+
// serve it — has nothing to call.
|
|
72
|
+
throw new IamClientError(`runtime-api:${clientId}`);
|
|
73
|
+
}
|
|
74
|
+
return base.replace(/\/+$/, '');
|
|
75
|
+
})();
|
|
76
|
+
known.set(clientId, attempt);
|
|
77
|
+
attempt.catch(() => {
|
|
78
|
+
if (known.get(clientId) === attempt) {
|
|
79
|
+
known.delete(clientId);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
return attempt;
|
|
83
|
+
};
|
|
84
|
+
const scope = makeOrganizationScope(context, request);
|
|
85
|
+
const call = async ({ method, path, access, params, query, body }) => {
|
|
86
|
+
const record = await scope.sessionOf();
|
|
87
|
+
const clientId = record.client ?? context.service(OIDC_CLIENT_SERVICE).getDefault();
|
|
88
|
+
if (clientId == null) {
|
|
89
|
+
throw new AuthUnavailable('oidc-client');
|
|
90
|
+
}
|
|
91
|
+
const token = record.payload?.access_token;
|
|
92
|
+
if (token == null || token === '') {
|
|
93
|
+
throw new AuthForbidden('record');
|
|
94
|
+
}
|
|
95
|
+
const url = new URL(`${await runtimeBase(clientId)}${pathOf(path, params)}`);
|
|
96
|
+
Object.entries(query ?? {}).forEach(([key, value]) => {
|
|
97
|
+
if (value != null) {
|
|
98
|
+
url.searchParams.set(key, String(value));
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
const response = await fetch(url, {
|
|
102
|
+
method,
|
|
103
|
+
headers: {
|
|
104
|
+
authorization: `Bearer ${token}`,
|
|
105
|
+
accept: 'application/json',
|
|
106
|
+
...(method === 'POST' ? { 'content-type': 'application/json' } : {}),
|
|
107
|
+
},
|
|
108
|
+
// A JSON content type with an empty body is refused by the server, so a POST always sends one.
|
|
109
|
+
...(method === 'POST' ? { body: JSON.stringify(body ?? {}) } : {}),
|
|
110
|
+
});
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw await failureOf(response, access);
|
|
113
|
+
}
|
|
114
|
+
return await response.json();
|
|
115
|
+
};
|
|
116
|
+
const R = IAM_RUNTIME_ROUTES;
|
|
117
|
+
return {
|
|
118
|
+
organizations: {
|
|
119
|
+
list: async () => (await call({
|
|
120
|
+
method: 'GET', path: R.organizations, access: 'subject',
|
|
121
|
+
})).items,
|
|
122
|
+
create: async (body) => call({
|
|
123
|
+
method: 'POST', path: R.organizations, access: 'subject', body: body ?? {},
|
|
124
|
+
}),
|
|
125
|
+
update: async (entitySlug, body) => call({
|
|
126
|
+
method: 'POST', path: R.organization, access: 'owner', params: { entitySlug }, body,
|
|
127
|
+
}),
|
|
128
|
+
},
|
|
129
|
+
members: {
|
|
130
|
+
list: async (entitySlug) => (await call({
|
|
131
|
+
method: 'GET', path: R.members, access: 'member', params: { entitySlug },
|
|
132
|
+
})).items,
|
|
133
|
+
add: async (entitySlug, invite) => call({
|
|
134
|
+
method: 'POST', path: R.members, access: 'owner', params: { entitySlug }, body: invite,
|
|
135
|
+
}),
|
|
136
|
+
update: async (entitySlug, profileId, update) => call({
|
|
137
|
+
method: 'POST', path: R.member, access: 'owner', params: { entitySlug, profileId }, body: update,
|
|
138
|
+
}),
|
|
139
|
+
remove: async (entitySlug, profileId) => {
|
|
140
|
+
await call({
|
|
141
|
+
method: 'POST', path: R.memberRemove, access: 'owner', params: { entitySlug, profileId },
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
permissions: {
|
|
146
|
+
list: async (entitySlug) => (await call({
|
|
147
|
+
method: 'GET', path: R.permissions, access: 'member', params: { entitySlug },
|
|
148
|
+
})).items,
|
|
149
|
+
},
|
|
150
|
+
grants: {
|
|
151
|
+
list: async (entitySlug, query) => (await call({
|
|
152
|
+
method: 'GET', path: R.grants, access: 'owner', params: { entitySlug }, query,
|
|
153
|
+
})).items,
|
|
154
|
+
assign: async (entitySlug, grant) => call({
|
|
155
|
+
method: 'POST', path: R.grants, access: 'owner', params: { entitySlug }, body: grant,
|
|
156
|
+
}),
|
|
157
|
+
revoke: async (entitySlug, grant) => {
|
|
158
|
+
await call({
|
|
159
|
+
method: 'POST', path: R.grantsRevoke, access: 'owner', params: { entitySlug }, body: grant,
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
/** @deprecated compat:factory-refactor — use `makeIamRuntimeClient(context, request)` */
|
|
166
|
+
export const iamRuntime = (context, request) => makeIamRuntimeClient(context, request);
|
|
167
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
package/build/types.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { IamRuntimeGrant, IamRuntimeGrantQuery, IamRuntimeGrantRequest, IamRuntimeMember, IamRuntimeMemberInvite, IamRuntimeMemberUpdate, IamRuntimeOrganization, IamRuntimeOrganizationCreate, IamRuntimeOrganizationUpdate, IamRuntimePermission } from '@owlmeans/iam';
|
|
2
|
+
export interface IamGateOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Refuse a resource-scoped param on the UMA2 fallback path instead of widening it to a
|
|
5
|
+
* project-wide check.
|
|
6
|
+
*
|
|
7
|
+
* Off by default, and deliberately so. A Keycloak-backed deployment cannot hold a resource-scoped
|
|
8
|
+
* grant at all — the adapter throws `IamUnsupported('resource-scoped-grant')` — so denying would
|
|
9
|
+
* lock every user out of every scoped endpoint rather than tightening anything. Turn it on only
|
|
10
|
+
* where the resulting refusals are the intended outcome.
|
|
11
|
+
*/
|
|
12
|
+
strictResourceScope?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The runtime IAM API as the signed-in subject of one request: its organizations, their members,
|
|
16
|
+
* the grantable definitions and the grants. Every call acts as that subject — the provider decides
|
|
17
|
+
* owner and member rights from the access token, never from anything sent here.
|
|
18
|
+
*/
|
|
19
|
+
export interface IamRuntimeClient {
|
|
20
|
+
organizations: {
|
|
21
|
+
list: () => Promise<IamRuntimeOrganization[]>;
|
|
22
|
+
/** The subject becomes the new organization's owner. */
|
|
23
|
+
create: (body?: IamRuntimeOrganizationCreate) => Promise<IamRuntimeOrganization>;
|
|
24
|
+
update: (entitySlug: string, body: IamRuntimeOrganizationUpdate) => Promise<IamRuntimeOrganization>;
|
|
25
|
+
};
|
|
26
|
+
members: {
|
|
27
|
+
list: (entitySlug: string) => Promise<IamRuntimeMember[]>;
|
|
28
|
+
/** Find-or-create by e-mail: adding an address twice answers the same member. */
|
|
29
|
+
add: (entitySlug: string, invite: IamRuntimeMemberInvite) => Promise<IamRuntimeMember>;
|
|
30
|
+
update: (entitySlug: string, profileId: string, update: IamRuntimeMemberUpdate) => Promise<IamRuntimeMember>;
|
|
31
|
+
remove: (entitySlug: string, profileId: string) => Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
permissions: {
|
|
34
|
+
list: (entitySlug: string) => Promise<IamRuntimePermission[]>;
|
|
35
|
+
};
|
|
36
|
+
grants: {
|
|
37
|
+
list: (entitySlug: string, query?: IamRuntimeGrantQuery) => Promise<IamRuntimeGrant[]>;
|
|
38
|
+
assign: (entitySlug: string, grant: IamRuntimeGrantRequest) => Promise<IamRuntimeGrant>;
|
|
39
|
+
revoke: (entitySlug: string, grant: IamRuntimeGrantRequest) => Promise<void>;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAE9Q,MAAM,WAAW,cAAc;IAC7B;;;;;;;;OAQG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE;QACb,IAAI,EAAE,MAAM,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAA;QAC7C,wDAAwD;QACxD,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,4BAA4B,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAA;QAChF,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,4BAA4B,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAA;KACpG,CAAA;IACD,OAAO,EAAE;QACP,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAA;QACzD,iFAAiF;QACjF,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;QACtF,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;QAC5G,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KACjE,CAAA;IACD,WAAW,EAAE;QACX,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAA;KAC9D,CAAA;IACD,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;QACtF,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;QACvF,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAC7E,CAAA;CACF"}
|
package/build/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
|
|
2
|
+
import type { WithSharedConfig } from '@owlmeans/oidc';
|
|
3
|
+
export interface IamServerConfig extends ServerConfig, WithSharedConfig {
|
|
4
|
+
}
|
|
5
|
+
export type IamServerContext<C extends IamServerConfig = IamServerConfig> = ServerContext<C>;
|
|
6
|
+
/** Who a route admits — and therefore which refusal a bare 403 from it means. */
|
|
7
|
+
export type Access = 'subject' | 'member' | 'owner';
|
|
8
|
+
export interface Call {
|
|
9
|
+
method: 'GET' | 'POST';
|
|
10
|
+
path: string;
|
|
11
|
+
access: Access;
|
|
12
|
+
params?: Record<string, string>;
|
|
13
|
+
query?: object;
|
|
14
|
+
body?: object;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=types.local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,MAAM,WAAW,eAAgB,SAAQ,YAAY,EAAE,gBAAgB;CAAG;AAE1E,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,IAAI,aAAa,CAAC,CAAC,CAAC,CAAA;AAE5F,iFAAiF;AACjF,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;AAEnD,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.local.js","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/server-iam",
|
|
3
|
-
"version": "0.1.18
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -22,17 +22,19 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@owlmeans/auth": "^0.1.18
|
|
26
|
-
"@owlmeans/context": "^0.1.18
|
|
27
|
-
"@owlmeans/entrypoint": "^0.1.18
|
|
28
|
-
"@owlmeans/
|
|
29
|
-
"@owlmeans/
|
|
30
|
-
"@owlmeans/
|
|
31
|
-
"@owlmeans/
|
|
25
|
+
"@owlmeans/auth": "^0.1.18",
|
|
26
|
+
"@owlmeans/context": "^0.1.18",
|
|
27
|
+
"@owlmeans/entrypoint": "^0.1.18",
|
|
28
|
+
"@owlmeans/error": "^0.1.18",
|
|
29
|
+
"@owlmeans/iam": "^0.1.18",
|
|
30
|
+
"@owlmeans/log": "^0.1.18",
|
|
31
|
+
"@owlmeans/oidc": "^0.1.18",
|
|
32
|
+
"@owlmeans/server-context": "^0.1.18",
|
|
33
|
+
"@owlmeans/server-oidc-rp": "^0.1.18"
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
34
|
-
"@owlmeans/dep-config": "
|
|
35
|
-
"@types/bun": "^1.
|
|
36
|
+
"@owlmeans/dep-config": "^0.1.18",
|
|
37
|
+
"@types/bun": "^1.4.2",
|
|
36
38
|
"nodemon": "^3.1.14",
|
|
37
39
|
"typescript": "^7.0.2"
|
|
38
40
|
},
|
package/src/append.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type { ServerConfig, ServerContext } from '@owlmeans/server-context'
|
|
2
|
-
import type { WithSharedConfig } from '@owlmeans/oidc'
|
|
3
1
|
import { appendOidcGuard, makeOidcClientService, makeOidcWrappingService } from '@owlmeans/server-oidc-rp'
|
|
4
2
|
import { makeIamGate } from './gate.js'
|
|
3
|
+
import type { IamServerConfig, IamServerContext } from './types.local.js'
|
|
5
4
|
|
|
6
|
-
type IamServerConfig = ServerConfig & WithSharedConfig
|
|
7
|
-
type IamServerContext<C extends IamServerConfig = IamServerConfig> = ServerContext<C>
|
|
8
5
|
|
|
9
6
|
/**
|
|
10
7
|
* One-call OIDC RP setup for a server context.
|