@selvajs/server 1.4.0 → 1.5.0-beta.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/api/bodies.d.ts +10 -2
- package/dist/api/bodies.d.ts.map +1 -1
- package/dist/api/bodies.js +9 -1
- package/dist/api/bodies.js.map +1 -1
- package/dist/api/deps.d.ts +3 -0
- package/dist/api/deps.d.ts.map +1 -1
- package/dist/api/deps.js.map +1 -1
- package/dist/api/errors.d.ts +6 -2
- package/dist/api/errors.d.ts.map +1 -1
- package/dist/api/errors.js +9 -4
- package/dist/api/errors.js.map +1 -1
- package/dist/api/index.d.ts +4 -3
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +3 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/respond.d.ts +22 -9
- package/dist/api/respond.d.ts.map +1 -1
- package/dist/api/respond.js +12 -11
- package/dist/api/respond.js.map +1 -1
- package/dist/api/responses-schema.d.ts +32 -2
- package/dist/api/responses-schema.d.ts.map +1 -1
- package/dist/api/responses-schema.js +24 -2
- package/dist/api/responses-schema.js.map +1 -1
- package/dist/api/scope.d.ts +22 -0
- package/dist/api/scope.d.ts.map +1 -0
- package/dist/api/scope.js +63 -0
- package/dist/api/scope.js.map +1 -0
- package/dist/handlers/apiTokens.d.ts +23 -0
- package/dist/handlers/apiTokens.d.ts.map +1 -0
- package/dist/handlers/apiTokens.js +166 -0
- package/dist/handlers/apiTokens.js.map +1 -0
- package/dist/handlers/index.d.ts +1 -0
- package/dist/handlers/index.d.ts.map +1 -1
- package/dist/handlers/index.js +1 -0
- package/dist/handlers/index.js.map +1 -1
- package/dist/handlers/orgMembers.js +2 -2
- package/dist/handlers/orgMembers.js.map +1 -1
- package/dist/handlers/reclaim.js +2 -2
- package/dist/handlers/reclaim.js.map +1 -1
- package/dist/http/api-token.d.ts +46 -0
- package/dist/http/api-token.d.ts.map +1 -0
- package/dist/http/api-token.js +97 -0
- package/dist/http/api-token.js.map +1 -0
- package/dist/http/index.d.ts +2 -0
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +2 -0
- package/dist/http/index.js.map +1 -1
- package/dist/http/request-context.d.ts +24 -0
- package/dist/http/request-context.d.ts.map +1 -0
- package/dist/http/request-context.js +27 -0
- package/dist/http/request-context.js.map +1 -0
- package/dist/logging/PinoLogger.d.ts.map +1 -1
- package/dist/logging/PinoLogger.js +7 -1
- package/dist/logging/PinoLogger.js.map +1 -1
- package/dist/testing/harness.d.ts +5 -1
- package/dist/testing/harness.d.ts.map +1 -1
- package/dist/testing/harness.js +5 -9
- package/dist/testing/harness.js.map +1 -1
- package/dist/tokens/api-token-codec.d.ts +25 -0
- package/dist/tokens/api-token-codec.d.ts.map +1 -0
- package/dist/tokens/api-token-codec.js +70 -0
- package/dist/tokens/api-token-codec.js.map +1 -0
- package/dist/tokens/index.d.ts +1 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +2 -0
- package/dist/tokens/index.js.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API tokens: mint, list, revoke.
|
|
3
|
+
*
|
|
4
|
+
* **Session-only.** A key can't manage keys, so a leaked one can't mint more or
|
|
5
|
+
* revoke the owner's others to cover its tracks.
|
|
6
|
+
*
|
|
7
|
+
* **The raw key exists only in the mint response.** The store holds its HMAC,
|
|
8
|
+
* and every response goes through a schema that has no `tokenHash`.
|
|
9
|
+
*/
|
|
10
|
+
import { randomUUID } from 'node:crypto';
|
|
11
|
+
import { describeApiScope, hasPermission, parseApiScope } from '@selvajs/platform';
|
|
12
|
+
import { renderApiTokenCreatedEmail } from '@selvajs/notifications';
|
|
13
|
+
import { apiError, ApiErrorCode, ApiTokenResponseSchema, CreateApiTokenBodySchema, CreatedApiTokenResponseSchema, isApiError, noContent, parseBody, parseListOptions, requireCaller, requireParams, scopeRefusalsToday, shapedCollection } from '../api/index.js';
|
|
14
|
+
import { requireActingOrg, requireCanViewProject, requireManageOrgMembers, requirePermission } from '../access/index.js';
|
|
15
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
16
|
+
function requireSessionInOrg(req) {
|
|
17
|
+
if (req.ctx?.apiScope) {
|
|
18
|
+
apiError(403, ApiErrorCode.FORBIDDEN, 'API tokens can’t manage API tokens. Sign in to the web app to do this.');
|
|
19
|
+
}
|
|
20
|
+
return requireActingOrg(req, req.params.orgId);
|
|
21
|
+
}
|
|
22
|
+
function unavailable() {
|
|
23
|
+
apiError(503, ApiErrorCode.API_TOKENS_UNAVAILABLE, 'API tokens are not available on this server.');
|
|
24
|
+
}
|
|
25
|
+
function storeOf(req) {
|
|
26
|
+
return req.deps.data.apiTokens ?? unavailable();
|
|
27
|
+
}
|
|
28
|
+
function codecOf(req) {
|
|
29
|
+
return req.deps.tokens.apiTokens ?? unavailable();
|
|
30
|
+
}
|
|
31
|
+
function toResponse(token) {
|
|
32
|
+
return { ...token, refusedToday: scopeRefusalsToday(token.id) };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Refuse scopes naming something outside this org or out of the creator's
|
|
36
|
+
* sight. Not the security boundary: a key never exceeds its owner's live rights
|
|
37
|
+
* anyway. This stops someone minting a key that can only ever be refused.
|
|
38
|
+
*/
|
|
39
|
+
async function assertScopesReachable(req, orgId, scopes) {
|
|
40
|
+
const refuse = (message) => apiError(400, ApiErrorCode.VALIDATION_FAILED, message, { scopes: message });
|
|
41
|
+
for (const value of scopes) {
|
|
42
|
+
const scope = parseApiScope(value) ?? refuse(`Unknown scope: ${value}`);
|
|
43
|
+
const { resource } = scope;
|
|
44
|
+
if (resource.kind === 'all')
|
|
45
|
+
continue;
|
|
46
|
+
if (resource.kind === 'org') {
|
|
47
|
+
if (resource.id !== orgId)
|
|
48
|
+
refuse('An org scope must name this org.');
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
let projectId = resource.id;
|
|
52
|
+
if (resource.kind === 'definition') {
|
|
53
|
+
const record = (await req.deps.definitionMeta.get(req.ctx, resource.id)) ??
|
|
54
|
+
refuse(`No definition ${resource.id}.`);
|
|
55
|
+
projectId = record.projectId;
|
|
56
|
+
}
|
|
57
|
+
const project = await req.deps.projects.getProject(req.ctx, projectId);
|
|
58
|
+
if (!project || project.orgId !== orgId)
|
|
59
|
+
refuse(`No ${resource.kind} ${resource.id} in this org.`);
|
|
60
|
+
try {
|
|
61
|
+
await requireCanViewProject(req, projectId);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (isApiError(err))
|
|
65
|
+
refuse(`You can’t access ${resource.kind} ${resource.id}.`);
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Tell the owner a key now exists on their account, best-effort. The case that
|
|
72
|
+
* matters is the one where they didn't make it.
|
|
73
|
+
*/
|
|
74
|
+
async function mailTokenCreated(req, token) {
|
|
75
|
+
const notifications = req.deps.notifications;
|
|
76
|
+
const to = req.user?.email;
|
|
77
|
+
if (!notifications || !to)
|
|
78
|
+
return;
|
|
79
|
+
try {
|
|
80
|
+
const org = await req.deps.orgs.getOrg(req.ctx, token.orgId);
|
|
81
|
+
await notifications.send(renderApiTokenCreatedEmail({
|
|
82
|
+
to,
|
|
83
|
+
tokenName: token.name,
|
|
84
|
+
orgName: org?.name ?? req.deps.instanceName,
|
|
85
|
+
scopes: token.scopes.map(describeApiScope),
|
|
86
|
+
expiresAt: token.expiresAt,
|
|
87
|
+
manageUrl: `${req.url.origin}/admin/tokens`
|
|
88
|
+
}), req.log);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
req.log.warn('API token mail could not be sent', {
|
|
92
|
+
component: 'ApiTokens',
|
|
93
|
+
tokenId: token.id,
|
|
94
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The caller's own tokens in this org, newest first, including revoked and
|
|
100
|
+
* expired ones. `?all=true` returns everyone's and needs `manage_org_members`.
|
|
101
|
+
*/
|
|
102
|
+
export const listApiTokens = async (req) => {
|
|
103
|
+
const { ctx, orgId } = requireSessionInOrg(req);
|
|
104
|
+
const all = req.url.searchParams.get('all') === 'true';
|
|
105
|
+
if (all)
|
|
106
|
+
requireManageOrgMembers(req);
|
|
107
|
+
const page = await storeOf(req).listByOrg(ctx, orgId, {
|
|
108
|
+
...parseListOptions(req.url),
|
|
109
|
+
userId: all ? undefined : ctx.userId
|
|
110
|
+
});
|
|
111
|
+
return shapedCollection(ApiTokenResponseSchema, { ...page, items: page.items.map(toResponse) });
|
|
112
|
+
};
|
|
113
|
+
/** Mint a token acting as the caller. The raw key is in this response and nowhere else. */
|
|
114
|
+
export const createApiToken = async (req) => {
|
|
115
|
+
const { ctx, orgId } = requireSessionInOrg(req);
|
|
116
|
+
requirePermission(req, 'manage_api_tokens');
|
|
117
|
+
const { user } = requireCaller(req);
|
|
118
|
+
const store = storeOf(req);
|
|
119
|
+
const codec = codecOf(req);
|
|
120
|
+
// A key minted now would only ever get 503.
|
|
121
|
+
const delegated = req.deps.auth.delegatedSession;
|
|
122
|
+
if (delegated && !(await delegated.status()).ok)
|
|
123
|
+
unavailable();
|
|
124
|
+
const input = await parseBody(req.request, CreateApiTokenBodySchema);
|
|
125
|
+
await assertScopesReachable(req, orgId, input.scopes);
|
|
126
|
+
const raw = codec.mintRawToken();
|
|
127
|
+
const now = new Date();
|
|
128
|
+
const token = {
|
|
129
|
+
id: randomUUID(),
|
|
130
|
+
userId: user.id,
|
|
131
|
+
createdBy: user.id,
|
|
132
|
+
orgId,
|
|
133
|
+
name: input.name,
|
|
134
|
+
tokenHash: codec.hashToken(raw),
|
|
135
|
+
scopes: [...new Set(input.scopes)],
|
|
136
|
+
createdAt: now.toISOString(),
|
|
137
|
+
expiresAt: new Date(now.getTime() + input.expiresInDays * DAY_MS).toISOString(),
|
|
138
|
+
lastUsedAt: null,
|
|
139
|
+
revokedAt: null
|
|
140
|
+
};
|
|
141
|
+
await store.create(ctx, token);
|
|
142
|
+
await mailTokenCreated(req, token);
|
|
143
|
+
const { tokenHash: _hash, ...summary } = token;
|
|
144
|
+
return {
|
|
145
|
+
status: 201,
|
|
146
|
+
headers: { 'Cache-Control': 'no-store' },
|
|
147
|
+
body: CreatedApiTokenResponseSchema.parse({ token: toResponse(summary), secret: raw })
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Revoke a token: the owner's own, or anyone's in the org for
|
|
152
|
+
* `manage_org_members`. Someone else's token reads as missing, not forbidden.
|
|
153
|
+
*/
|
|
154
|
+
export const revokeApiToken = async (req) => {
|
|
155
|
+
const { ctx, orgId } = requireSessionInOrg(req);
|
|
156
|
+
const { tokenId } = requireParams(req.params, 'tokenId');
|
|
157
|
+
const store = storeOf(req);
|
|
158
|
+
const token = await store.get(ctx, tokenId);
|
|
159
|
+
const own = token?.userId === ctx.userId;
|
|
160
|
+
if (!token || token.orgId !== orgId || (!own && !hasPermission(ctx, 'manage_org_members'))) {
|
|
161
|
+
apiError(404, ApiErrorCode.NOT_FOUND, 'API token not found');
|
|
162
|
+
}
|
|
163
|
+
await store.revoke(ctx, tokenId, own ? 'owner' : 'admin');
|
|
164
|
+
return noContent();
|
|
165
|
+
};
|
|
166
|
+
//# sourceMappingURL=apiTokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiTokens.js","sourceRoot":"","sources":["../../src/handlers/apiTokens.ts"],"names":[],"mappings":"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"}
|
package/dist/handlers/index.d.ts
CHANGED
|
@@ -24,4 +24,5 @@ export { listProjects, createProject, getProject, updateProject, deleteProject }
|
|
|
24
24
|
export { listProjectMembers, addProjectMember, updateProjectMemberRole, removeProjectMember } from './projectMembers.js';
|
|
25
25
|
export { getOrgCompute, updateOrgCompute } from './orgCompute.js';
|
|
26
26
|
export { listInvites, createInvite, revokeInvite, resendInvite } from './invites.js';
|
|
27
|
+
export { listApiTokens, createApiToken, revokeApiToken } from './apiTokens.js';
|
|
27
28
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/handlers/index.js
CHANGED
|
@@ -26,4 +26,5 @@ export { listProjects, createProject, getProject, updateProject, deleteProject }
|
|
|
26
26
|
export { listProjectMembers, addProjectMember, updateProjectMemberRole, removeProjectMember } from './projectMembers.js';
|
|
27
27
|
export { getOrgCompute, updateOrgCompute } from './orgCompute.js';
|
|
28
28
|
export { listInvites, createInvite, revokeInvite, resendInvite } from './invites.js';
|
|
29
|
+
export { listApiTokens, createApiToken, revokeApiToken } from './apiTokens.js';
|
|
29
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,8EAA8E;AAC9E,8EAA8E;AAC9E,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,8EAA8E;AAC9E,8EAA8E;AAC9E,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* demoting them does.
|
|
12
12
|
*/
|
|
13
13
|
import { apiError, ApiErrorCode, noContent, parseBody, requireParams, UpdateOrgMemberBodySchema } from '../api/index.js';
|
|
14
|
-
import { MEMBER_ASSIGNABLE_PERMISSIONS, ALL_ORG_PERMISSIONS,
|
|
14
|
+
import { MEMBER_ASSIGNABLE_PERMISSIONS, ALL_ORG_PERMISSIONS, actorOf, canChangeOrgRole } from '@selvajs/platform';
|
|
15
15
|
import { requireManageOrgMembers, requireActingOrg } from '../access/index.js';
|
|
16
16
|
const ROSTER_PAGE_LIMIT = 200;
|
|
17
17
|
// Runaway guard against an adapter returning a non-advancing cursor. Matches
|
|
@@ -167,7 +167,7 @@ export const removeOrgMember = async (req) => {
|
|
|
167
167
|
orgId,
|
|
168
168
|
userId,
|
|
169
169
|
projectIds: orphaned.map((p) => p.id),
|
|
170
|
-
|
|
170
|
+
...actorOf(ctx)
|
|
171
171
|
});
|
|
172
172
|
req.log.warn('Org member removal left projects without an owner', {
|
|
173
173
|
orgId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orgMembers.js","sourceRoot":"","sources":["../../src/handlers/orgMembers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACN,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,EACT,aAAa,EACb,yBAAyB,EACzB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,6BAA6B,EAC7B,mBAAmB,EACnB,
|
|
1
|
+
{"version":3,"file":"orgMembers.js","sourceRoot":"","sources":["../../src/handlers/orgMembers.ts"],"names":[],"mappings":"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"}
|
package/dist/handlers/reclaim.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* reactivates a soft-deleted row in place.
|
|
7
7
|
*/
|
|
8
8
|
import { created, requireParams } from '../api/index.js';
|
|
9
|
-
import {
|
|
9
|
+
import { actorOf } from '@selvajs/platform';
|
|
10
10
|
import { requireCanReclaim } from '../access/index.js';
|
|
11
11
|
export const reclaimProject = async (req) => {
|
|
12
12
|
const { id } = requireParams(req.params, 'id');
|
|
@@ -30,7 +30,7 @@ export const reclaimProject = async (req) => {
|
|
|
30
30
|
type: 'project.reclaimed',
|
|
31
31
|
projectId: id,
|
|
32
32
|
orgId: project.orgId,
|
|
33
|
-
|
|
33
|
+
...actorOf(ctx),
|
|
34
34
|
priorVisibility: project.visibility
|
|
35
35
|
});
|
|
36
36
|
return created({ member });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reclaim.js","sourceRoot":"","sources":["../../src/handlers/reclaim.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"reclaim.js","sourceRoot":"","sources":["../../src/handlers/reclaim.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAsB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,CAAC,MAAM,cAAc,GAAe,KAAK,EAAE,GAAG,EAAE,EAAE;IACvD,MAAM,EAAE,EAAE,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAEhE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,MAAM,GAAkB;QAC7B,SAAS,EAAE,EAAE;QACb,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,GAAG;QACb,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE;QAChC,SAAS,EAAE,IAAI;KACf,CAAC;IAEF,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAEtD,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,qCAAqC;IACrC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QAC1B,IAAI,EAAE,mBAAmB;QACzB,SAAS,EAAE,EAAE;QACb,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,GAAG,OAAO,CAAC,GAAG,CAAC;QACf,eAAe,EAAE,OAAO,CAAC,UAAU;KACnC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AAC5B,CAAC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ApiToken, AuthUser, IAuthProvider, IDataProvider, ILogger, RequestContext } from '@selvajs/platform';
|
|
2
|
+
import { ApiErrorCode } from '../api/errors.js';
|
|
3
|
+
import { type ApiTokenCodec } from '../tokens/api-token-codec.js';
|
|
4
|
+
export type ApiTokenResolution =
|
|
5
|
+
/** No API token on the request. Carry on with the cookie or proxy path. */
|
|
6
|
+
{
|
|
7
|
+
kind: 'none';
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'ok';
|
|
10
|
+
user: AuthUser;
|
|
11
|
+
ctx: RequestContext;
|
|
12
|
+
token: ApiToken;
|
|
13
|
+
}
|
|
14
|
+
/** Answer with this and stop. Never fall back to another sign-in path. */
|
|
15
|
+
| {
|
|
16
|
+
kind: 'rejected';
|
|
17
|
+
status: number;
|
|
18
|
+
code: ApiErrorCode;
|
|
19
|
+
message: string;
|
|
20
|
+
};
|
|
21
|
+
export interface ResolveApiTokenDeps {
|
|
22
|
+
/** Absent when the host hasn't configured API tokens: a sent key gets 503. */
|
|
23
|
+
codec?: ApiTokenCodec;
|
|
24
|
+
auth: Pick<IAuthProvider, 'getUser' | 'delegatedSession'>;
|
|
25
|
+
data: Pick<IDataProvider, 'apiTokens' | 'orgs'>;
|
|
26
|
+
/** Receives background failures (the `lastUsedAt` write). Logs the token id only. */
|
|
27
|
+
log?: ILogger;
|
|
28
|
+
now?: () => number;
|
|
29
|
+
}
|
|
30
|
+
export interface ResolveApiTokenOptions {
|
|
31
|
+
/** Keys work under this prefix and are refused everywhere else. */
|
|
32
|
+
pathPrefix?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Authenticate a request by its `Authorization: Bearer selva_…` header.
|
|
36
|
+
*
|
|
37
|
+
* Call it before any cookie or proxy sign-in. Once a `selva_` key is sent the
|
|
38
|
+
* outcome is final: a bad key gets 401 even if a valid session cookie rides
|
|
39
|
+
* along, because running the request as the cookie's user would hide the
|
|
40
|
+
* broken key and act as someone else.
|
|
41
|
+
*
|
|
42
|
+
* The owner is re-checked on every request (disabled, still a member of the
|
|
43
|
+
* token's org), then their live context is narrowed to the token's scopes.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveApiToken(request: Request, deps: ResolveApiTokenDeps, { pathPrefix }?: ResolveApiTokenOptions): Promise<ApiTokenResolution>;
|
|
46
|
+
//# sourceMappingURL=api-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-token.d.ts","sourceRoot":"","sources":["../../src/http/api-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,aAAa,EACb,OAAO,EACP,cAAc,EACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAGN,KAAK,aAAa,EAClB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,MAAM,kBAAkB;AAC7B,2EAA2E;AACzE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE;AACtE,0EAA0E;GACxE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,mBAAmB;IACnC,8EAA8E;IAC9E,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,kBAAkB,CAAC,CAAC;IAC1D,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,MAAM,CAAC,CAAC;IAChD,qFAAqF;IACrF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAmBD;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,mBAAmB,EACzB,EAAE,UAAuB,EAAE,GAAE,sBAA2B,GACtD,OAAO,CAAC,kBAAkB,CAAC,CAsE7B"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { SYSTEM_CONTEXT, narrowApiTokenContext } from '@selvajs/platform';
|
|
2
|
+
import { ApiErrorCode } from '../api/errors.js';
|
|
3
|
+
import { API_TOKEN_PREFIX, looksLikeApiToken } from '../tokens/api-token-codec.js';
|
|
4
|
+
import { buildRequestContext } from './request-context.js';
|
|
5
|
+
/** `lastUsedAt` is written at most this often per token, so a busy key isn't a write per request. */
|
|
6
|
+
const LAST_USED_WRITE_INTERVAL_MS = 5 * 60 * 1000;
|
|
7
|
+
const UNAUTHORIZED = {
|
|
8
|
+
kind: 'rejected',
|
|
9
|
+
status: 401,
|
|
10
|
+
code: ApiErrorCode.UNAUTHORIZED,
|
|
11
|
+
message: 'This API token is invalid, expired or revoked.'
|
|
12
|
+
};
|
|
13
|
+
const UNAVAILABLE = {
|
|
14
|
+
kind: 'rejected',
|
|
15
|
+
status: 503,
|
|
16
|
+
code: ApiErrorCode.API_TOKENS_UNAVAILABLE,
|
|
17
|
+
message: 'API tokens are not available on this server.'
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Authenticate a request by its `Authorization: Bearer selva_…` header.
|
|
21
|
+
*
|
|
22
|
+
* Call it before any cookie or proxy sign-in. Once a `selva_` key is sent the
|
|
23
|
+
* outcome is final: a bad key gets 401 even if a valid session cookie rides
|
|
24
|
+
* along, because running the request as the cookie's user would hide the
|
|
25
|
+
* broken key and act as someone else.
|
|
26
|
+
*
|
|
27
|
+
* The owner is re-checked on every request (disabled, still a member of the
|
|
28
|
+
* token's org), then their live context is narrowed to the token's scopes.
|
|
29
|
+
*/
|
|
30
|
+
export async function resolveApiToken(request, deps, { pathPrefix = '/api/v1/' } = {}) {
|
|
31
|
+
const url = new URL(request.url);
|
|
32
|
+
for (const value of url.searchParams.values()) {
|
|
33
|
+
if (looksLikeApiToken(value)) {
|
|
34
|
+
return {
|
|
35
|
+
kind: 'rejected',
|
|
36
|
+
status: 400,
|
|
37
|
+
code: ApiErrorCode.VALIDATION_FAILED,
|
|
38
|
+
message: 'API tokens go in the Authorization header, never the URL. URLs end up in logs and browser history; revoke this key.'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const raw = bearerOf(request);
|
|
43
|
+
if (!raw?.startsWith(API_TOKEN_PREFIX))
|
|
44
|
+
return { kind: 'none' };
|
|
45
|
+
if (!url.pathname.startsWith(pathPrefix)) {
|
|
46
|
+
return {
|
|
47
|
+
kind: 'rejected',
|
|
48
|
+
status: 403,
|
|
49
|
+
code: ApiErrorCode.FORBIDDEN,
|
|
50
|
+
message: `API tokens only work under ${pathPrefix}.`
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const store = deps.data.apiTokens;
|
|
54
|
+
if (!deps.codec || !store)
|
|
55
|
+
return UNAVAILABLE;
|
|
56
|
+
// The provider logs why; the admin health page shows it.
|
|
57
|
+
const delegated = deps.auth.delegatedSession;
|
|
58
|
+
if (delegated && !(await delegated.status()).ok)
|
|
59
|
+
return UNAVAILABLE;
|
|
60
|
+
if (!deps.codec.hasValidChecksum(raw))
|
|
61
|
+
return UNAUTHORIZED;
|
|
62
|
+
const token = await store.getByTokenHash(SYSTEM_CONTEXT, deps.codec.hashToken(raw));
|
|
63
|
+
if (!token)
|
|
64
|
+
return UNAUTHORIZED;
|
|
65
|
+
const [user, member] = await Promise.all([
|
|
66
|
+
deps.auth.getUser(token.userId),
|
|
67
|
+
deps.data.orgs.getOrgMember(SYSTEM_CONTEXT, token.orgId, token.userId)
|
|
68
|
+
]);
|
|
69
|
+
if (!user || user.disabled || !member)
|
|
70
|
+
return UNAUTHORIZED;
|
|
71
|
+
// Platform permissions aren't read: narrowing drops them anyway.
|
|
72
|
+
let ctx = narrowApiTokenContext(await buildRequestContext({ user, platformPermissions: [], membership: member, pinOrg: true }, { orgs: deps.data.orgs }), token);
|
|
73
|
+
// Signed only after the user check above: a minted session can't be
|
|
74
|
+
// revoked, and row security doesn't look at bans.
|
|
75
|
+
if (delegated) {
|
|
76
|
+
ctx = { ...ctx, adapterContext: { sessionToken: await delegated.mint(user.id) } };
|
|
77
|
+
}
|
|
78
|
+
const now = deps.now?.() ?? Date.now();
|
|
79
|
+
if (!token.lastUsedAt || now - Date.parse(token.lastUsedAt) >= LAST_USED_WRITE_INTERVAL_MS) {
|
|
80
|
+
store.touchLastUsed(SYSTEM_CONTEXT, token.id, new Date(now).toISOString()).catch((err) => {
|
|
81
|
+
deps.log?.warn('Failed to record API token use', {
|
|
82
|
+
component: 'apiToken',
|
|
83
|
+
tokenId: token.id,
|
|
84
|
+
err: err instanceof Error ? err.message : String(err)
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return { kind: 'ok', user, ctx, token };
|
|
89
|
+
}
|
|
90
|
+
function bearerOf(request) {
|
|
91
|
+
const header = request.headers.get('authorization');
|
|
92
|
+
if (!header)
|
|
93
|
+
return null;
|
|
94
|
+
const match = /^Bearer\s+(\S+)\s*$/i.exec(header);
|
|
95
|
+
return match ? match[1] : null;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=api-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-token.js","sourceRoot":"","sources":["../../src/http/api-token.ts"],"names":[],"mappings":"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"}
|
package/dist/http/index.d.ts
CHANGED
|
@@ -3,4 +3,6 @@ export { declaredBodySizeExceeds, type HeadersLike } from './body-size.js';
|
|
|
3
3
|
export { applySecurityHeaders, type SecurityHeaderOptions } from './security-headers.js';
|
|
4
4
|
export { createRouteClassifier, type RouteClassifier, type RouteClassifierConfig } from './route-classifier.js';
|
|
5
5
|
export { createLoginRateLimiter, addressKeysCollapsed, type LoginRateLimiter, type LoginRateLimiterConfig } from './login-rate-limit.js';
|
|
6
|
+
export { buildRequestContext, type BuildRequestContextInput } from './request-context.js';
|
|
7
|
+
export { resolveApiToken, type ApiTokenResolution, type ResolveApiTokenDeps, type ResolveApiTokenOptions } from './api-token.js';
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/http/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EACN,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EACpB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EACN,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EACpB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EACN,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,MAAM,gBAAgB,CAAC"}
|
package/dist/http/index.js
CHANGED
|
@@ -4,4 +4,6 @@ export { declaredBodySizeExceeds } from './body-size.js';
|
|
|
4
4
|
export { applySecurityHeaders } from './security-headers.js';
|
|
5
5
|
export { createRouteClassifier } from './route-classifier.js';
|
|
6
6
|
export { createLoginRateLimiter, addressKeysCollapsed } from './login-rate-limit.js';
|
|
7
|
+
export { buildRequestContext } from './request-context.js';
|
|
8
|
+
export { resolveApiToken } from './api-token.js';
|
|
7
9
|
//# sourceMappingURL=index.js.map
|
package/dist/http/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAoB,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAA8B,MAAM,uBAAuB,CAAC;AACzF,OAAO,EACN,qBAAqB,EAGrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EAGpB,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAoB,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAA8B,MAAM,uBAAuB,CAAC;AACzF,OAAO,EACN,qBAAqB,EAGrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,sBAAsB,EACtB,oBAAoB,EAGpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAiC,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EACN,eAAe,EAIf,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AuthUser, IOrgStore, OrgMember, PlatformPermission, RequestContext } from '@selvajs/platform';
|
|
2
|
+
export interface BuildRequestContextInput {
|
|
3
|
+
user: AuthUser;
|
|
4
|
+
platformPermissions: PlatformPermission[];
|
|
5
|
+
/** The membership the request acts through, or null for none. */
|
|
6
|
+
membership: Pick<OrgMember, 'orgId' | 'permissions'> | null;
|
|
7
|
+
/** Forwarded as `adapterContext.sessionToken`; Supabase scopes row security by it. */
|
|
8
|
+
sessionToken?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Act in `membership`'s org or nowhere. Turns off the instance-admin
|
|
11
|
+
* first-org fallback: an API token is bound to one org.
|
|
12
|
+
*/
|
|
13
|
+
pinOrg?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* One request's identity: the acting org and the permissions held there.
|
|
17
|
+
*
|
|
18
|
+
* Every sign-in path builds through here (cookie, forward-auth, API token, and
|
|
19
|
+
* any host app's own hook), so they can't drift on what a context contains.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildRequestContext(input: BuildRequestContextInput, deps: {
|
|
22
|
+
orgs: Pick<IOrgStore, 'listOrgs'>;
|
|
23
|
+
}): Promise<RequestContext>;
|
|
24
|
+
//# sourceMappingURL=request-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/http/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,QAAQ,EACR,SAAS,EACT,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,QAAQ,CAAC;IACf,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,iEAAiE;IACjE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,aAAa,CAAC,GAAG,IAAI,CAAC;IAC5D,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACxC,KAAK,EAAE,wBAAwB,EAC/B,IAAI,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;CAAE,GACzC,OAAO,CAAC,cAAc,CAAC,CAmBzB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SYSTEM_CONTEXT } from '@selvajs/platform';
|
|
2
|
+
/**
|
|
3
|
+
* One request's identity: the acting org and the permissions held there.
|
|
4
|
+
*
|
|
5
|
+
* Every sign-in path builds through here (cookie, forward-auth, API token, and
|
|
6
|
+
* any host app's own hook), so they can't drift on what a context contains.
|
|
7
|
+
*/
|
|
8
|
+
export async function buildRequestContext(input, deps) {
|
|
9
|
+
const { user, platformPermissions, membership, sessionToken, pinOrg } = input;
|
|
10
|
+
let actingOrgId = membership?.orgId;
|
|
11
|
+
const orgPermissions = membership ? [...membership.permissions] : [];
|
|
12
|
+
if (!actingOrgId && !pinOrg && platformPermissions.includes('instance_admin')) {
|
|
13
|
+
// Instance admins without a membership fall back to the first org, so admin
|
|
14
|
+
// tooling stays usable before an org switcher exists.
|
|
15
|
+
const firstOrg = (await deps.orgs.listOrgs(SYSTEM_CONTEXT, { limit: 1 })).items[0];
|
|
16
|
+
if (firstOrg)
|
|
17
|
+
actingOrgId = firstOrg.id;
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
userId: user.id,
|
|
21
|
+
actingOrgId,
|
|
22
|
+
platformPermissions,
|
|
23
|
+
orgPermissions,
|
|
24
|
+
adapterContext: sessionToken ? { sessionToken } : undefined
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=request-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/http/request-context.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAgBnD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,KAA+B,EAC/B,IAA2C;IAE3C,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAC9E,IAAI,WAAW,GAAG,UAAU,EAAE,KAAK,CAAC;IACpC,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAErE,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,IAAI,mBAAmB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC/E,4EAA4E;QAC5E,sDAAsD;QACtD,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnF,IAAI,QAAQ;YAAE,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC;IACzC,CAAC;IAED,OAAO;QACN,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,WAAW;QACX,mBAAmB;QACnB,cAAc;QACd,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS;KAC3D,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinoLogger.d.ts","sourceRoot":"","sources":["../../src/logging/PinoLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"PinoLogger.d.ts","sourceRoot":"","sources":["../../src/logging/PinoLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAiEtE;;;;GAIG;AACH,qBAAa,aAAc,YAAW,OAAO;IAE3C,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,KAAK,GAAE,SAAc,EACrB,QAAQ,GAAE,QAAiB;IAG7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAK3B;IAEF,OAAO,CAAC,KAAK;IAYb,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI;IAGhD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI;IAG/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI;IAG/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI;IAGhD,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO;CAGjC;AAqDD,MAAM,WAAW,mBAAmB;IACnC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,IAAI,CAAC,EAAE,SAAS,CAAC;CACjB;AAED,uEAAuE;AACvE,wBAAsB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAuBnF"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* It matches by FIELD NAME, and only at the top level or one level deep (the
|
|
8
8
|
* `*.` entries). It will not catch personal data — an email nested in a payload
|
|
9
9
|
* sails straight through, and a log line reaches a collector that erasure can
|
|
10
|
-
* never reach.
|
|
10
|
+
* never reach. The nested `*.` set doesn't cover every top-level name.
|
|
11
11
|
*/
|
|
12
12
|
const REDACTED_PATHS = [
|
|
13
13
|
'token',
|
|
@@ -17,7 +17,13 @@ const REDACTED_PATHS = [
|
|
|
17
17
|
'api_key',
|
|
18
18
|
'password',
|
|
19
19
|
'authorization',
|
|
20
|
+
'Authorization',
|
|
20
21
|
'cookie',
|
|
22
|
+
// A freshly minted API token is returned as `secret`.
|
|
23
|
+
'secret',
|
|
24
|
+
'*.secret',
|
|
25
|
+
'*.authorization',
|
|
26
|
+
'*.Authorization',
|
|
21
27
|
'*.token',
|
|
22
28
|
'*.sessionToken',
|
|
23
29
|
'*.refreshToken',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinoLogger.js","sourceRoot":"","sources":["../../src/logging/PinoLogger.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PinoLogger.js","sourceRoot":"","sources":["../../src/logging/PinoLogger.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* production returns 403, and every status assertion silently weakens.
|
|
16
16
|
*/
|
|
17
17
|
import { emptyProfile, type AuthUser, type DefinitionRecord, type DefinitionVersion, type ILogger, type OrgMember, type OrgPermission, type OrgRole, type Organization, type PlatformPermission, type Project, type ProjectMember, type ProjectRole, type ProjectVisibility, type RequestContext, type SelvaConfig, type ShareLink } from '@selvajs/platform';
|
|
18
|
-
import type { ApiError, ApiHandler, SelvaDeps } from '../api/index.js';
|
|
18
|
+
import type { ApiError, ApiHandler, RunHandlerOptions, SelvaDeps } from '../api/index.js';
|
|
19
19
|
import type { SeedAuthAdapter } from './seed-adapter.js';
|
|
20
20
|
export interface TestHarness {
|
|
21
21
|
config: SelvaConfig;
|
|
@@ -147,6 +147,10 @@ export interface CallHandlerOpts {
|
|
|
147
147
|
url?: string;
|
|
148
148
|
body?: unknown;
|
|
149
149
|
headers?: Record<string, string>;
|
|
150
|
+
/** Defaults to POST with a body, GET without. */
|
|
151
|
+
method?: string;
|
|
152
|
+
/** The options a route passes to `mount`, so scope checks run as they do in production. */
|
|
153
|
+
mount?: Pick<RunHandlerOptions, 'action' | 'scopeTarget'>;
|
|
150
154
|
}
|
|
151
155
|
export interface CallResult {
|
|
152
156
|
status: number;
|