@tangle-network/sandbox 0.0.0-develop.20260514223840.b2abd84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,220 @@
1
+ //#region src/auth/types.d.ts
2
+ /**
3
+ * Auth Types
4
+ *
5
+ * Self-contained type definitions for token issuance.
6
+ * No external dependencies (no zod, no internal packages).
7
+ */
8
+ /**
9
+ * Token scope types for multi-tenant access control.
10
+ *
11
+ * - "session": Access to a single session (requires sid)
12
+ * - "project": Access to all sessions within a project (requires projectId)
13
+ * - "batch": Access to multiple projects (requires projectIds array)
14
+ * - "collaboration": Access to a single collaborative document
15
+ */
16
+ type TokenScope = "session" | "project" | "batch" | "collaboration";
17
+ /**
18
+ * Base token payload fields (common across all scopes).
19
+ */
20
+ interface BaseTokenPayload {
21
+ /** Subject: User ID */
22
+ sub: string;
23
+ /** Product ID (used to look up signing secret) */
24
+ pid: string;
25
+ /** Sandbox runtime ID (optional, for direct routing) */
26
+ cid?: string;
27
+ /** Issued at (Unix timestamp, seconds) */
28
+ iat: number;
29
+ /** Expires at (Unix timestamp, seconds) */
30
+ exp: number;
31
+ }
32
+ interface ReadBaseTokenPayload extends BaseTokenPayload {
33
+ /** Token type for session/project/batch event subscriptions */
34
+ typ: "read";
35
+ }
36
+ /**
37
+ * Session-scoped token payload.
38
+ * Grants access to a single session's events.
39
+ */
40
+ interface SessionScopedTokenPayload extends ReadBaseTokenPayload {
41
+ /** Session ID */
42
+ sid: string;
43
+ projectId?: undefined;
44
+ projectIds?: undefined;
45
+ }
46
+ /**
47
+ * Project-scoped token payload.
48
+ * Grants access to all sessions within a single project.
49
+ */
50
+ interface ProjectScopedTokenPayload extends ReadBaseTokenPayload {
51
+ sid?: undefined;
52
+ /** Project ID */
53
+ projectId: string;
54
+ projectIds?: undefined;
55
+ }
56
+ /**
57
+ * Batch-scoped token payload.
58
+ * Grants access to multiple projects (organization-level access).
59
+ */
60
+ interface BatchScopedTokenPayload extends ReadBaseTokenPayload {
61
+ sid?: undefined;
62
+ projectId?: undefined;
63
+ /** Project IDs */
64
+ projectIds: string[];
65
+ }
66
+ type CollaborationAccess = "read" | "write";
67
+ /**
68
+ * Collaboration-scoped token payload.
69
+ * Grants access to a single collaborative document in one project.
70
+ */
71
+ interface CollaborationTokenPayload extends BaseTokenPayload {
72
+ typ: "collaboration";
73
+ sid: string;
74
+ projectId: string;
75
+ documentId: string;
76
+ access: CollaborationAccess;
77
+ }
78
+ interface IssueCollaborationTokenOptions {
79
+ sessionId: string;
80
+ projectId: string;
81
+ documentId: string;
82
+ access: CollaborationAccess;
83
+ userId: string;
84
+ productId: string;
85
+ sandboxId?: string;
86
+ }
87
+ /**
88
+ * Union of all token payload types.
89
+ */
90
+ type ReadTokenPayload = SessionScopedTokenPayload | ProjectScopedTokenPayload | BatchScopedTokenPayload;
91
+ type AnyTokenPayload = ReadTokenPayload | CollaborationTokenPayload;
92
+ //#endregion
93
+ //#region src/auth/tokens.d.ts
94
+ /**
95
+ * Issue a read token (JWT) for WebSocket authentication.
96
+ *
97
+ * @param signingSecret - The product's signing secret
98
+ * @param payload - Token payload (without iat/exp/typ, those are added)
99
+ * @param ttlMinutes - Token TTL in minutes
100
+ */
101
+ declare function issueReadToken(signingSecret: string, payload: Omit<ReadTokenPayload, "iat" | "exp" | "typ">, ttlMinutes: number): string;
102
+ /**
103
+ * Issue a session-scoped token (JWT) for WebSocket authentication.
104
+ * Grants access to a single session's events.
105
+ */
106
+ declare function issueSessionScopedToken(signingSecret: string, payload: Omit<ReadTokenPayload, "iat" | "exp" | "typ">, ttlMinutes: number): string;
107
+ /**
108
+ * Issue a project-scoped token (JWT) for WebSocket authentication.
109
+ * Grants access to all sessions within a single project.
110
+ */
111
+ declare function issueProjectScopedToken(signingSecret: string, payload: Omit<ReadTokenPayload, "iat" | "exp" | "typ">, ttlMinutes: number): string;
112
+ /**
113
+ * Issue a batch-scoped token (JWT) for WebSocket authentication.
114
+ * Grants access to multiple projects (organization-level access).
115
+ */
116
+ declare function issueBatchScopedToken(signingSecret: string, payload: Omit<ReadTokenPayload, "iat" | "exp" | "typ">, ttlMinutes: number): string;
117
+ /**
118
+ * Issue a collaboration-scoped token (JWT) for collaborative document access.
119
+ * Grants read or write access to a single document in one project.
120
+ */
121
+ declare function issueCollaborationToken(signingSecret: string, payload: IssueCollaborationTokenOptions, ttlMinutes: number): string;
122
+ /**
123
+ * Decode a JWT **without verifying its signature**.
124
+ *
125
+ * The deliberately scary name is the API contract: an HMAC-signed token
126
+ * whose signature has not been verified is a self-asserted blob of JSON,
127
+ * not an authenticated claim. Treating its fields as authoritative
128
+ * (e.g. `if (unsafeDecodeToken(t).sub === userId) grantAccess()`) is a
129
+ * straightforward authorization bypass — an attacker can mint any
130
+ * payload they like.
131
+ *
132
+ * Use this only when the signature has already been validated upstream
133
+ * (e.g. by an API gateway that strips the token after verification),
134
+ * for client-side `exp` peeking to decide whether to refresh, or for
135
+ * routing/logging keyed off non-security-sensitive claims.
136
+ *
137
+ * For any access-control decision, use {@link verifyToken} instead.
138
+ *
139
+ * Returns `null` if the token is malformed.
140
+ */
141
+ declare function unsafeDecodeToken(token: string): AnyTokenPayload | null;
142
+ /**
143
+ * Verify a JWT's HMAC-SHA256 signature against `signingSecret` and
144
+ * check that it has not expired. Returns the decoded payload on
145
+ * success, or `null` on any failure (malformed token, bad signature,
146
+ * expired, or unexpected algorithm).
147
+ *
148
+ * Signature comparison is constant-time. Callers must use this — not
149
+ * {@link unsafeDecodeToken} — for any authorization decision.
150
+ *
151
+ * @param token - The JWT to verify
152
+ * @param signingSecret - The same secret used to issue the token
153
+ * @param options.clockSkewSeconds - Tolerance for `exp` checks; default `0`
154
+ */
155
+ declare function verifyToken(token: string, signingSecret: string, options?: {
156
+ clockSkewSeconds?: number;
157
+ }): AnyTokenPayload | null;
158
+ /**
159
+ * Get time until token expires (in seconds).
160
+ * Returns negative if expired.
161
+ */
162
+ declare function getTokenTTL(payload: AnyTokenPayload): number;
163
+ /**
164
+ * Check if token is expiring soon (within buffer seconds).
165
+ */
166
+ declare function isTokenExpiringSoon(payload: AnyTokenPayload, bufferSeconds?: number): boolean;
167
+ //#endregion
168
+ //#region src/auth/index.d.ts
169
+ /**
170
+ * Token issuer for application backend services.
171
+ *
172
+ * Use this in your backend to issue read tokens for WebSocket connections.
173
+ */
174
+ declare class ProductTokenIssuer {
175
+ private readonly productId;
176
+ private readonly signingSecret;
177
+ private readonly ttlMinutes;
178
+ constructor(config: {
179
+ productId: string;
180
+ signingSecret: string; /** TTL in minutes for each tier (default: { free: 15, pro: 240 }) */
181
+ ttlMinutes?: {
182
+ free?: number;
183
+ pro?: number;
184
+ enterprise?: number;
185
+ };
186
+ });
187
+ /**
188
+ * Issue a read token for a user session.
189
+ */
190
+ issue(params: {
191
+ userId: string;
192
+ sessionId: string;
193
+ tier?: "free" | "pro" | "enterprise";
194
+ sandboxId?: string;
195
+ }): {
196
+ token: string;
197
+ expiresAt: number;
198
+ };
199
+ /**
200
+ * Issue a collaboration token for a single document.
201
+ */
202
+ issueCollaboration(params: {
203
+ userId: string;
204
+ sessionId: string;
205
+ projectId: string;
206
+ documentId: string;
207
+ access: "read" | "write";
208
+ tier?: "free" | "pro" | "enterprise";
209
+ sandboxId?: string;
210
+ }): {
211
+ token: string;
212
+ expiresAt: number;
213
+ };
214
+ /**
215
+ * Get the TTL in minutes for a tier.
216
+ */
217
+ getTtlMinutes(tier?: "free" | "pro" | "enterprise"): number;
218
+ }
219
+ //#endregion
220
+ export { ReadTokenPayload as _, issueCollaborationToken as a, issueSessionScopedToken as c, AnyTokenPayload as d, BatchScopedTokenPayload as f, ProjectScopedTokenPayload as g, IssueCollaborationTokenOptions as h, issueBatchScopedToken as i, unsafeDecodeToken as l, CollaborationTokenPayload as m, getTokenTTL as n, issueProjectScopedToken as o, CollaborationAccess as p, isTokenExpiringSoon as r, issueReadToken as s, ProductTokenIssuer as t, verifyToken as u, SessionScopedTokenPayload as v, TokenScope as y };