@camstack/server 1.2.486 → 1.2.487
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/agent/agent-mesh-join.js +80 -0
- package/dist/agent/main.js +61 -2
- package/dist/api/auth-whoami.js +1 -1
- package/dist/api/core/auth-admin-tokens.procedures.js +138 -0
- package/dist/api/core/auth-limits.js +77 -0
- package/dist/api/core/auth-reauth.procedures.js +108 -0
- package/dist/api/core/auth-sessions.procedures.js +166 -0
- package/dist/api/core/auth.router.js +281 -80
- package/dist/api/health/adaptive-probe.routes.js +1 -1
- package/dist/api/trpc/core-cap-bridge.js +47 -5
- package/dist/api/trpc/generated-cap-mounts.js +19 -1
- package/dist/api/trpc/generated-cap-routers.js +512 -205
- package/dist/api/trpc/trpc.context.js +86 -34
- package/dist/api/trpc/trpc.middleware.js +8 -11
- package/dist/api/trpc/trpc.router.js +6 -1
- package/dist/auth/auth-network-policy.js +75 -0
- package/dist/auth/auth-rate-limit.js +25 -20
- package/dist/auth/client-address.js +68 -0
- package/dist/auth/external-link-intents.js +12 -3
- package/dist/auth/hub-sessions.js +74 -0
- package/dist/auth/native-link-completions.js +68 -0
- package/dist/auth/native-return.js +33 -0
- package/dist/auth/session-lifetimes.js +46 -0
- package/dist/auth/session-mint.js +110 -13
- package/dist/auth/sso-finish-deps.js +56 -1
- package/dist/auth/sso-finish.js +132 -17
- package/dist/auth/sso-routes.js +95 -0
- package/dist/auth/used-bridge-ids.js +52 -0
- package/dist/core/addon/addon-registry.service.js +5 -0
- package/dist/core/agent/agent-registry.service.js +10 -0
- package/dist/core/auth/auth.service.js +50 -1
- package/dist/core/auth/handoff-code.service.js +9 -3
- package/dist/core/moleculer/hub-mesh-guard.js +132 -0
- package/dist/core/moleculer/moleculer.service.js +33 -0
- package/dist/main.js +92 -28
- package/package.json +13 -13
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RefreshResultSchema = exports.LoginSessionSchema = void 0;
|
|
4
|
+
exports.createSessionProcedures = createSessionProcedures;
|
|
5
|
+
const server_1 = require("@trpc/server");
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const hub_sessions_js_1 = require("../../auth/hub-sessions.js");
|
|
8
|
+
const session_mint_js_1 = require("../../auth/session-mint.js");
|
|
9
|
+
const trpc_middleware_js_1 = require("../trpc/trpc.middleware.js");
|
|
10
|
+
/** One login session as the UI lists it. */
|
|
11
|
+
exports.LoginSessionSchema = zod_1.z.object({
|
|
12
|
+
id: zod_1.z.string(),
|
|
13
|
+
userId: zod_1.z.string(),
|
|
14
|
+
method: zod_1.z.string(),
|
|
15
|
+
refreshable: zod_1.z.boolean(),
|
|
16
|
+
createdAt: zod_1.z.number(),
|
|
17
|
+
lastUsedAt: zod_1.z.number(),
|
|
18
|
+
expiresAt: zod_1.z.number(),
|
|
19
|
+
client: zod_1.z.string().nullable(),
|
|
20
|
+
ip: zod_1.z.string().nullable(),
|
|
21
|
+
/** The session this request was made with. */
|
|
22
|
+
current: zod_1.z.boolean(),
|
|
23
|
+
});
|
|
24
|
+
/** What a refresh returns: a new access token and the rotated refresh token. */
|
|
25
|
+
exports.RefreshResultSchema = zod_1.z.object({
|
|
26
|
+
token: zod_1.z.string(),
|
|
27
|
+
refreshToken: zod_1.z.string(),
|
|
28
|
+
expiresAt: zod_1.z.number(),
|
|
29
|
+
sessionId: zod_1.z.string(),
|
|
30
|
+
sessionExpiresAt: zod_1.z.number(),
|
|
31
|
+
user: zod_1.z.object({ id: zod_1.z.string(), username: zod_1.z.string(), isAdmin: zod_1.z.boolean() }),
|
|
32
|
+
});
|
|
33
|
+
function requireSessions(registry) {
|
|
34
|
+
const internal = registry === null ? null : (0, hub_sessions_js_1.userManagementInternal)(registry);
|
|
35
|
+
if (internal === null) {
|
|
36
|
+
throw new server_1.TRPCError({
|
|
37
|
+
code: 'PRECONDITION_FAILED',
|
|
38
|
+
message: 'Login sessions are not available',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return internal.sessions;
|
|
42
|
+
}
|
|
43
|
+
/** Real user sessions only — a scoped or share token has no login session to manage. */
|
|
44
|
+
function assertLoginSession(user) {
|
|
45
|
+
if (user.isScoped === true || user.shareView !== undefined || user.adminTokenId !== undefined) {
|
|
46
|
+
throw new server_1.TRPCError({ code: 'FORBIDDEN', message: 'Requires a signed-in user session' });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function createSessionProcedures(deps) {
|
|
50
|
+
const list = (userId, currentId) => {
|
|
51
|
+
const sessions = requireSessions(deps.registry);
|
|
52
|
+
const rows = userId === null ? sessions.listActive() : sessions.listForUser(userId);
|
|
53
|
+
return rows.map((row) => ({
|
|
54
|
+
id: row.id,
|
|
55
|
+
userId: row.userId,
|
|
56
|
+
method: row.method,
|
|
57
|
+
refreshable: row.refreshable,
|
|
58
|
+
createdAt: row.createdAt,
|
|
59
|
+
lastUsedAt: row.lastUsedAt,
|
|
60
|
+
expiresAt: row.expiresAt,
|
|
61
|
+
client: row.client,
|
|
62
|
+
ip: row.ip,
|
|
63
|
+
current: row.id === currentId,
|
|
64
|
+
}));
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
/**
|
|
68
|
+
* PUBLIC — swap a refresh token for a new access token and a rotated
|
|
69
|
+
* refresh token; the session's expiry slides. A rotated-out token
|
|
70
|
+
* presented again (outside a short grace) is treated as stolen and ends
|
|
71
|
+
* the session. Any refusal is a 401: the client signs in again.
|
|
72
|
+
*/
|
|
73
|
+
refreshSession: deps.credentialProcedure
|
|
74
|
+
.input(zod_1.z.object({ refreshToken: zod_1.z.string().min(1).max(512) }))
|
|
75
|
+
.output(exports.RefreshResultSchema)
|
|
76
|
+
.mutation(async ({ input }) => {
|
|
77
|
+
try {
|
|
78
|
+
const minted = await deps.minter.refresh(input.refreshToken);
|
|
79
|
+
if (minted.refreshToken === undefined ||
|
|
80
|
+
minted.sessionId === undefined ||
|
|
81
|
+
minted.expiresAt === undefined ||
|
|
82
|
+
minted.sessionExpiresAt === undefined) {
|
|
83
|
+
throw new session_mint_js_1.SessionRefreshRefusedError('unknown');
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
token: minted.token,
|
|
87
|
+
refreshToken: minted.refreshToken,
|
|
88
|
+
expiresAt: minted.expiresAt,
|
|
89
|
+
sessionId: minted.sessionId,
|
|
90
|
+
sessionExpiresAt: minted.sessionExpiresAt,
|
|
91
|
+
user: minted.user,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (error instanceof session_mint_js_1.SessionRefreshRefusedError ||
|
|
96
|
+
error instanceof session_mint_js_1.SessionUserGoneError) {
|
|
97
|
+
throw new server_1.TRPCError({
|
|
98
|
+
code: 'UNAUTHORIZED',
|
|
99
|
+
message: 'Session expired — sign in again',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}),
|
|
105
|
+
/**
|
|
106
|
+
* End the caller's session on the server (its access and refresh tokens
|
|
107
|
+
* stop working at once). `everywhere: true` ends every session of the
|
|
108
|
+
* user, and their pre-session tokens.
|
|
109
|
+
*/
|
|
110
|
+
logout: trpc_middleware_js_1.protectedProcedure
|
|
111
|
+
.input(zod_1.z.object({ everywhere: zod_1.z.boolean().optional() }).optional())
|
|
112
|
+
.output(zod_1.z.object({ success: zod_1.z.literal(true), revoked: zod_1.z.number() }))
|
|
113
|
+
.mutation(async ({ ctx, input }) => {
|
|
114
|
+
assertLoginSession(ctx.user);
|
|
115
|
+
const sessions = requireSessions(deps.registry);
|
|
116
|
+
if (input?.everywhere === true) {
|
|
117
|
+
const revoked = await sessions.revokeAllForUser(ctx.user.id, {
|
|
118
|
+
reason: 'logout-everywhere',
|
|
119
|
+
});
|
|
120
|
+
return { success: true, revoked };
|
|
121
|
+
}
|
|
122
|
+
const sessionId = ctx.user.sessionId;
|
|
123
|
+
const revoked = sessionId === undefined ? false : await sessions.revoke(sessionId, 'logout');
|
|
124
|
+
return { success: true, revoked: revoked ? 1 : 0 };
|
|
125
|
+
}),
|
|
126
|
+
/** The caller's live sessions, newest first; `current` marks this one. */
|
|
127
|
+
listOwnSessions: trpc_middleware_js_1.protectedProcedure
|
|
128
|
+
.input(zod_1.z.void())
|
|
129
|
+
.output(zod_1.z.array(exports.LoginSessionSchema))
|
|
130
|
+
.query(({ ctx }) => {
|
|
131
|
+
assertLoginSession(ctx.user);
|
|
132
|
+
return list(ctx.user.id, ctx.user.sessionId);
|
|
133
|
+
}),
|
|
134
|
+
/** End one of the caller's own sessions (another device). */
|
|
135
|
+
revokeOwnSession: trpc_middleware_js_1.protectedProcedure
|
|
136
|
+
.input(zod_1.z.object({ id: zod_1.z.string().min(1) }))
|
|
137
|
+
.output(zod_1.z.object({ success: zod_1.z.boolean() }))
|
|
138
|
+
.mutation(async ({ ctx, input }) => {
|
|
139
|
+
assertLoginSession(ctx.user);
|
|
140
|
+
const sessions = requireSessions(deps.registry);
|
|
141
|
+
const check = sessions.check(input.id);
|
|
142
|
+
if (check.state !== 'active' || check.session.userId !== ctx.user.id) {
|
|
143
|
+
return { success: false };
|
|
144
|
+
}
|
|
145
|
+
return { success: await sessions.revoke(input.id, 'revoked-by-user') };
|
|
146
|
+
}),
|
|
147
|
+
/** ADMIN — live sessions of one user, or of everyone. */
|
|
148
|
+
listSessions: trpc_middleware_js_1.adminProcedure
|
|
149
|
+
.input(zod_1.z.object({ userId: zod_1.z.string().min(1).optional() }).optional())
|
|
150
|
+
.output(zod_1.z.array(exports.LoginSessionSchema))
|
|
151
|
+
.query(({ ctx, input }) => list(input?.userId ?? null, ctx.user.sessionId)),
|
|
152
|
+
/** ADMIN — end one session, or every session of a user. */
|
|
153
|
+
revokeSessions: trpc_middleware_js_1.adminProcedure
|
|
154
|
+
.input(zod_1.z.union([zod_1.z.object({ id: zod_1.z.string().min(1) }), zod_1.z.object({ userId: zod_1.z.string().min(1) })]))
|
|
155
|
+
.output(zod_1.z.object({ revoked: zod_1.z.number() }))
|
|
156
|
+
.mutation(async ({ input }) => {
|
|
157
|
+
const sessions = requireSessions(deps.registry);
|
|
158
|
+
if ('id' in input) {
|
|
159
|
+
return { revoked: (await sessions.revoke(input.id, 'revoked-by-admin')) ? 1 : 0 };
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
revoked: await sessions.revokeAllForUser(input.userId, { reason: 'revoked-by-admin' }),
|
|
163
|
+
};
|
|
164
|
+
}),
|
|
165
|
+
};
|
|
166
|
+
}
|