@ganju/utils 0.0.4 → 0.0.5

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,25 @@
1
+ /** The SHA-256 of a presented token, in the encoding the column stores. */
2
+ export declare const hashAccessToken: (token: string) => Promise<string>;
3
+ /**
4
+ * Cheap enough to run before the database is touched: a bearer token that does
5
+ * not carry the prefix is an OAuth token, and belongs on the other path.
6
+ */
7
+ export declare const isAccessToken: (token: string) => boolean;
8
+ /**
9
+ * What the dashboard shows beside a token's name.
10
+ *
11
+ * Enough to tell two rows apart when someone is deciding which to revoke, and
12
+ * deliberately taken from the *front* of the secret rather than the end: a
13
+ * prefix narrows a brute-force search by exactly as much as a suffix would, and
14
+ * a value people are used to seeing truncated at the end reads as complete when
15
+ * it is the end that is shown.
16
+ */
17
+ export declare const accessTokenHint: (token: string) => string;
18
+ export interface MintedAccessToken {
19
+ /** The only time this value exists. Returned to the caller, never stored. */
20
+ token: string;
21
+ tokenHash: string;
22
+ hint: string;
23
+ }
24
+ export declare const mintAccessToken: () => Promise<MintedAccessToken>;
25
+ //# sourceMappingURL=accessToken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessToken.d.ts","sourceRoot":"","sources":["../src/accessToken.ts"],"names":[],"mappings":"AA+BA,2EAA2E;AAC3E,eAAO,MAAM,eAAe,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,CAMnE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,OACG,CAAC;AAElD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,MAI1B,CAAC;AAEvB,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,eAAe,QAAa,OAAO,CAAC,iBAAiB,CASjE,CAAC"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mintAccessToken = exports.accessTokenHint = exports.isAccessToken = exports.hashAccessToken = void 0;
4
+ const constants_1 = require("./constants");
5
+ /**
6
+ * Minting and recognising a personal access token.
7
+ *
8
+ * The value exists in plaintext exactly once — in the response to the request
9
+ * that created it — and what the database holds is its SHA-256. That is the
10
+ * property the whole credential rests on: a leaked backup, a stray log line, or
11
+ * a support engineer reading the row learns nothing they could present as the
12
+ * token, and there is no path in the product that can print one back, because
13
+ * there is nothing to print.
14
+ *
15
+ * SHA-256 rather than a password hash on purpose. A password is a low-entropy
16
+ * secret a person chose, so the cost of hashing it is what stands between a
17
+ * stolen table and the passwords in it; this is 32 bytes from a CSPRNG, where
18
+ * that cost buys nothing and would be paid on every authenticated request. It
19
+ * is also the hash `oauth_client.client_secret` already uses in this system, so
20
+ * there is one answer here to "how is a machine credential stored".
21
+ */
22
+ const HINT_SEPARATOR = '…';
23
+ const base64url = (bytes) => {
24
+ let binary = '';
25
+ for (const byte of bytes)
26
+ binary += String.fromCharCode(byte);
27
+ return btoa(binary)
28
+ .replace(/\+/g, '-')
29
+ .replace(/\//g, '_')
30
+ .replace(/=+$/, '');
31
+ };
32
+ /** The SHA-256 of a presented token, in the encoding the column stores. */
33
+ const hashAccessToken = async (token) => {
34
+ const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(token));
35
+ return base64url(new Uint8Array(digest));
36
+ };
37
+ exports.hashAccessToken = hashAccessToken;
38
+ /**
39
+ * Cheap enough to run before the database is touched: a bearer token that does
40
+ * not carry the prefix is an OAuth token, and belongs on the other path.
41
+ */
42
+ const isAccessToken = (token) => token.startsWith(constants_1.constants.ACCESS_TOKEN_PREFIX);
43
+ exports.isAccessToken = isAccessToken;
44
+ /**
45
+ * What the dashboard shows beside a token's name.
46
+ *
47
+ * Enough to tell two rows apart when someone is deciding which to revoke, and
48
+ * deliberately taken from the *front* of the secret rather than the end: a
49
+ * prefix narrows a brute-force search by exactly as much as a suffix would, and
50
+ * a value people are used to seeing truncated at the end reads as complete when
51
+ * it is the end that is shown.
52
+ */
53
+ const accessTokenHint = (token) => `${token.slice(0, constants_1.constants.ACCESS_TOKEN_PREFIX.length + constants_1.constants.ACCESS_TOKEN_HINT_CHARS)}${HINT_SEPARATOR}`;
54
+ exports.accessTokenHint = accessTokenHint;
55
+ const mintAccessToken = async () => {
56
+ const bytes = new Uint8Array(constants_1.constants.ACCESS_TOKEN_BYTES);
57
+ crypto.getRandomValues(bytes);
58
+ const token = `${constants_1.constants.ACCESS_TOKEN_PREFIX}${base64url(bytes)}`;
59
+ return {
60
+ token,
61
+ tokenHash: await (0, exports.hashAccessToken)(token),
62
+ hint: (0, exports.accessTokenHint)(token)
63
+ };
64
+ };
65
+ exports.mintAccessToken = mintAccessToken;
@@ -618,6 +618,15 @@ export declare const constants: {
618
618
  CLI_OAUTH_REDIRECT_PORTS: number[];
619
619
  CLI_OAUTH_SCOPES: string[];
620
620
  CLI_TOKEN_REFRESH_SKEW_SECONDS: number;
621
+ ACCESS_TOKEN_PREFIX: string;
622
+ ACCESS_TOKEN_BYTES: number;
623
+ ACCESS_TOKEN_HINT_CHARS: number;
624
+ ACCESS_TOKEN_NAME_MAX: number;
625
+ ACCESS_TOKEN_MAX_PER_PROJECT: number;
626
+ ACCESS_TOKEN_MAX_EXPIRY_DAYS: number;
627
+ ACCESS_TOKEN_LAST_USED_INTERVAL_MS: number;
628
+ ACCESS_TOKEN_UNSCOPED_PATHS: string[];
629
+ ACCESS_TOKEN_SCOPE_MESSAGE: string;
621
630
  CUSTOM_CODE_LOGS_DEFAULT_LIMIT: number;
622
631
  CUSTOM_CODE_LOGS_MAX_LIMIT: number;
623
632
  BOT_GRANT_TYPE: string;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
package/dist/constants.js CHANGED
@@ -1439,6 +1439,46 @@ const ARTIFACT_SCOPE_PREFIX = 'artifact:';
1439
1439
  // loopback matching, where the port is ignored for a 127.0.0.0/8 redirect, but
1440
1440
  // that is one library's behaviour and this is a login that has already opened
1441
1441
  // someone's browser by the time it would fail.
1442
+ // A personal access token — the durable credential a machine with no browser
1443
+ // uses, where an OAuth access token's one hour is not enough. Bound to one
1444
+ // project, because that is the unit a deploy pipeline works on: one repository,
1445
+ // one artifact, one credential in its CI settings.
1446
+ //
1447
+ // The prefix is part of the value rather than decoration: it is what lets the
1448
+ // middleware tell one of these from an OAuth token before it decides which
1449
+ // lookup to make, and it is what secret scanners match on when one leaks into a
1450
+ // repository. The rest is 32 random bytes, base64url — the token is the only
1451
+ // place the value ever exists in plaintext, since what is stored is its hash.
1452
+ const ACCESS_TOKEN_PREFIX = 'ganju_pat_';
1453
+ const ACCESS_TOKEN_BYTES = 32;
1454
+ // Enough of the secret to recognise a row by, and not enough to be worth
1455
+ // stealing. Shown in the dashboard and by `ganju token list` beside the name.
1456
+ const ACCESS_TOKEN_HINT_CHARS = 6;
1457
+ const ACCESS_TOKEN_NAME_MAX = 100;
1458
+ // A ceiling per project, so a compromised session cannot quietly mint an
1459
+ // unbounded set of credentials that each survive the session being ended.
1460
+ const ACCESS_TOKEN_MAX_PER_PROJECT = 20;
1461
+ // An expiry is optional, because a scheduled deploy that dies on a date nobody
1462
+ // wrote down is its own kind of outage — but a year is the longest we will
1463
+ // write one for.
1464
+ const ACCESS_TOKEN_MAX_EXPIRY_DAYS = 365;
1465
+ // `last_used_at` is a convenience, not an audit log, so it is written at most
1466
+ // this often per token rather than on every request. The question it answers —
1467
+ // "is anything still using this, or can I revoke it" — does not get a better
1468
+ // answer from minute-level precision, and the write would otherwise land on the
1469
+ // hot path of every CI request.
1470
+ const ACCESS_TOKEN_LAST_USED_INTERVAL_MS = 5 * 60 * 1000;
1471
+ // The only path a personal access token may reach without naming the project it
1472
+ // is scoped to, and only on GET. `/me` reports who the token is, which is how
1473
+ // the CLI confirms a machine is authenticated at all, and tells it nothing it
1474
+ // does not already hold.
1475
+ //
1476
+ // Everything else is refused, organization routes included — billing, members,
1477
+ // the model configs and the other projects are not what a deploy credential is
1478
+ // for. The list is deliberately this short: a route added later is closed by
1479
+ // omission rather than open by it.
1480
+ const ACCESS_TOKEN_UNSCOPED_PATHS = ['/me'];
1481
+ const ACCESS_TOKEN_SCOPE_MESSAGE = 'This token is scoped to a different project';
1442
1482
  // Recent custom-tool invocations, as `ganju logs` reads them.
1443
1483
  const CUSTOM_CODE_LOGS_DEFAULT_LIMIT = 20;
1444
1484
  const CUSTOM_CODE_LOGS_MAX_LIMIT = 100;
@@ -2267,6 +2307,15 @@ exports.constants = {
2267
2307
  CLI_OAUTH_REDIRECT_PORTS: cliConstants_1.CLI_OAUTH_REDIRECT_PORTS,
2268
2308
  CLI_OAUTH_SCOPES: cliConstants_1.CLI_OAUTH_SCOPES,
2269
2309
  CLI_TOKEN_REFRESH_SKEW_SECONDS: cliConstants_1.CLI_TOKEN_REFRESH_SKEW_SECONDS,
2310
+ ACCESS_TOKEN_PREFIX,
2311
+ ACCESS_TOKEN_BYTES,
2312
+ ACCESS_TOKEN_HINT_CHARS,
2313
+ ACCESS_TOKEN_NAME_MAX,
2314
+ ACCESS_TOKEN_MAX_PER_PROJECT,
2315
+ ACCESS_TOKEN_MAX_EXPIRY_DAYS,
2316
+ ACCESS_TOKEN_LAST_USED_INTERVAL_MS,
2317
+ ACCESS_TOKEN_UNSCOPED_PATHS,
2318
+ ACCESS_TOKEN_SCOPE_MESSAGE,
2270
2319
  CUSTOM_CODE_LOGS_DEFAULT_LIMIT,
2271
2320
  CUSTOM_CODE_LOGS_MAX_LIMIT,
2272
2321
  BOT_GRANT_TYPE,
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@ import type { OAuthProviderConfig } from './oauthProviders';
15
15
  import type { ExposableResource } from './exposedResource';
16
16
  import type { CustomCodeProject, ProjectPathIssue } from './customCodeProject';
17
17
  import type { AttachmentResource, ResolvedAttachment, ResolveAttachmentResult } from './attachment';
18
+ import type { MintedAccessToken } from './accessToken';
18
19
  import type { CatalogGroup, CatalogTool, CatalogToolDescriptor, ToolGroupKey, ToolKey } from './toolCatalog';
19
20
  import type { Separator, ChunkMetadata, PreparedChunk } from './chunking';
20
21
  import type { RateLimitRetryOptions } from './retry';
@@ -868,6 +869,28 @@ export declare const utils: {
868
869
  userId: import("zod").ZodUUID;
869
870
  organizationId: import("zod").ZodUUID;
870
871
  }, import("zod/v4/core").$strip>;
872
+ ACCESS_TOKEN_CREATE: import("zod").ZodObject<{
873
+ name: import("zod").ZodString;
874
+ expiresInDays: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodNumber>>;
875
+ userId: import("zod").ZodUUID;
876
+ organizationId: import("zod").ZodUUID;
877
+ projectId: import("zod").ZodUUID;
878
+ }, import("zod/v4/core").$strip>;
879
+ ACCESS_TOKEN_CREATE_VIEW: import("zod").ZodObject<{
880
+ name: import("zod").ZodString;
881
+ expiresInDays: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodNumber>>;
882
+ }, import("zod/v4/core").$strip>;
883
+ ACCESS_TOKEN_LIST: import("zod").ZodObject<{
884
+ userId: import("zod").ZodUUID;
885
+ organizationId: import("zod").ZodUUID;
886
+ projectId: import("zod").ZodUUID;
887
+ }, import("zod/v4/core").$strip>;
888
+ ACCESS_TOKEN_REMOVE: import("zod").ZodObject<{
889
+ tokenId: import("zod").ZodUUID;
890
+ userId: import("zod").ZodUUID;
891
+ organizationId: import("zod").ZodUUID;
892
+ projectId: import("zod").ZodUUID;
893
+ }, import("zod/v4/core").$strip>;
871
894
  CHANNEL_CONFIG: import("zod").ZodObject<{
872
895
  debounceMs: import("zod").ZodOptional<import("zod").ZodNumber>;
873
896
  }, import("zod/v4/core").$loose>;
@@ -2305,6 +2328,15 @@ export declare const utils: {
2305
2328
  CLI_OAUTH_REDIRECT_PORTS: number[];
2306
2329
  CLI_OAUTH_SCOPES: string[];
2307
2330
  CLI_TOKEN_REFRESH_SKEW_SECONDS: number;
2331
+ ACCESS_TOKEN_PREFIX: string;
2332
+ ACCESS_TOKEN_BYTES: number;
2333
+ ACCESS_TOKEN_HINT_CHARS: number;
2334
+ ACCESS_TOKEN_NAME_MAX: number;
2335
+ ACCESS_TOKEN_MAX_PER_PROJECT: number;
2336
+ ACCESS_TOKEN_MAX_EXPIRY_DAYS: number;
2337
+ ACCESS_TOKEN_LAST_USED_INTERVAL_MS: number;
2338
+ ACCESS_TOKEN_UNSCOPED_PATHS: string[];
2339
+ ACCESS_TOKEN_SCOPE_MESSAGE: string;
2308
2340
  CUSTOM_CODE_LOGS_DEFAULT_LIMIT: number;
2309
2341
  CUSTOM_CODE_LOGS_MAX_LIMIT: number;
2310
2342
  BOT_GRANT_TYPE: string;
@@ -2386,6 +2418,10 @@ export declare const utils: {
2386
2418
  languageFromHeader: (header?: string | null) => string;
2387
2419
  slugifyTitle: (title: string) => string;
2388
2420
  resourceUriFromTitle: (title: string) => string;
2421
+ accessTokenHint: (token: string) => string;
2422
+ hashAccessToken: (token: string) => Promise<string>;
2423
+ isAccessToken: (token: string) => boolean;
2424
+ mintAccessToken: () => Promise<MintedAccessToken>;
2389
2425
  TOOL_CATALOG: readonly [{
2390
2426
  readonly key: "gmail";
2391
2427
  readonly title: "Gmail";
@@ -2845,5 +2881,5 @@ export declare const utils: {
2845
2881
  PlanLimitError: typeof PlanLimitError;
2846
2882
  isPlanLimitError: (error: unknown) => error is PlanLimitError;
2847
2883
  };
2848
- export type { CustomCodeProject, ProjectPathIssue, CatalogGroup, CatalogTool, CatalogToolDescriptor, ToolGroupKey, ToolKey, CalendarConfigField, JsonSchema, SchemaViolation, MimeAttachment, MimeMessageInput, GmailOperation, GmailSendRequest, GmailSendResponse, OutlookOperation, OutlookSendRequest, OutlookSendResponse, SlackOperation, SlackSendRequest, SlackSendResponse, SlackSendRemoteResourceRequest, TelegramSendRequest, TelegramSendResponse, TelegramSendRemoteResourceRequest, DiscordSendRequest, DiscordSendResponse, DiscordSendRemoteResourceRequest, WhatsappSendRequest, WhatsappSendResponse, WhatsappSendRemoteResourceRequest, EnvSource, Separator, ChunkMetadata, PreparedChunk, ExtractedDocument, ExtractedDocumentMetadata, ExtractedDocumentSource, RateLimitRetryOptions, QueueBatchLike, QueueMessageLike, ProcessQueueBatchHandlers, ChannelNotifier, ToolStatusEvent, BufferedChannelMessage, ChannelBufferEnvelope, ChannelBufferFlush, Source, ResourceUrlContext, SourceButton, RefreshOAuthTokenInput, RefreshedOAuthToken, HttpEndpointToolConfig, McpProxyToolConfig, McpProxyDiscoveredTool, McpProxyDiscoveredResource, McpProxyDiscoveredPrompt, McpProxyDiscovery, CustomCodeToolConfig, CustomCodeToolManifest, CustomCodeManifest, CustomCodeSendFile, CustomCodeCreateResource, CustomCodeTokenPayload, OAuthProviderConfig, AttachmentResource, ResolvedAttachment, ResolveAttachmentResult, ExposableResource, PlanLimitDetails, PlanLimits };
2884
+ export type { MintedAccessToken, CustomCodeProject, ProjectPathIssue, CatalogGroup, CatalogTool, CatalogToolDescriptor, ToolGroupKey, ToolKey, CalendarConfigField, JsonSchema, SchemaViolation, MimeAttachment, MimeMessageInput, GmailOperation, GmailSendRequest, GmailSendResponse, OutlookOperation, OutlookSendRequest, OutlookSendResponse, SlackOperation, SlackSendRequest, SlackSendResponse, SlackSendRemoteResourceRequest, TelegramSendRequest, TelegramSendResponse, TelegramSendRemoteResourceRequest, DiscordSendRequest, DiscordSendResponse, DiscordSendRemoteResourceRequest, WhatsappSendRequest, WhatsappSendResponse, WhatsappSendRemoteResourceRequest, EnvSource, Separator, ChunkMetadata, PreparedChunk, ExtractedDocument, ExtractedDocumentMetadata, ExtractedDocumentSource, RateLimitRetryOptions, QueueBatchLike, QueueMessageLike, ProcessQueueBatchHandlers, ChannelNotifier, ToolStatusEvent, BufferedChannelMessage, ChannelBufferEnvelope, ChannelBufferFlush, Source, ResourceUrlContext, SourceButton, RefreshOAuthTokenInput, RefreshedOAuthToken, HttpEndpointToolConfig, McpProxyToolConfig, McpProxyDiscoveredTool, McpProxyDiscoveredResource, McpProxyDiscoveredPrompt, McpProxyDiscovery, CustomCodeToolConfig, CustomCodeToolManifest, CustomCodeManifest, CustomCodeSendFile, CustomCodeCreateResource, CustomCodeTokenPayload, OAuthProviderConfig, AttachmentResource, ResolvedAttachment, ResolveAttachmentResult, ExposableResource, PlanLimitDetails, PlanLimits };
2849
2885
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aArGf,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;kBAhHiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA0DF,CAAC;oBAEd,CAAC;;;;aA0BkB,CAAC;mBAA8B,CAAC;WACvC,CAAC;gBACf,CAAC;gBAA4B,CAAA;;;mBAoBK,CAAC;oBACjC,CAAC;;;;;;;;;;;;;;;kBA3Dc,CAAC;;;;;;;sBAqCR,CAAC;;;;;;;;;CA2Of,CAAC;AAEF,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,OAAO,EACP,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,8BAA8B,EAC9B,mBAAmB,EACnB,oBAAoB,EACpB,iCAAiC,EACjC,kBAAkB,EAClB,mBAAmB,EACnB,gCAAgC,EAChC,mBAAmB,EACnB,oBAAoB,EACpB,iCAAiC,EACjC,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,MAAM,EACN,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACX,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA5Gf,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;kBAhHiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA0DF,CAAC;oBAEd,CAAC;;;;aA0BkB,CAAC;mBAA8B,CAAC;WACvC,CAAC;gBACf,CAAC;gBAA4B,CAAA;;;mBAoBK,CAAC;oBACjC,CAAC;;;;;;;;;;;;;;;kBA3Dc,CAAC;;;;;;;sBAqCR,CAAC;;;;;;;;;CAsPf,CAAC;AAEF,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,OAAO,EACP,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,8BAA8B,EAC9B,mBAAmB,EACnB,oBAAoB,EACpB,iCAAiC,EACjC,kBAAkB,EAClB,mBAAmB,EACnB,gCAAgC,EAChC,mBAAmB,EACnB,oBAAoB,EACpB,iCAAiC,EACjC,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,MAAM,EACN,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACX,CAAC"}
package/dist/index.js CHANGED
@@ -31,6 +31,7 @@ const languageCookieDomain_1 = require("./languageCookieDomain");
31
31
  const localizeZodIssue_1 = require("./localizeZodIssue");
32
32
  const slugifyTitle_1 = require("./slugifyTitle");
33
33
  const resourceUri_1 = require("./resourceUri");
34
+ const accessToken_1 = require("./accessToken");
34
35
  const toolCatalog_1 = require("./toolCatalog");
35
36
  const tallyUsageKinds_1 = require("./tallyUsageKinds");
36
37
  const formatFilename_1 = require("./formatFilename");
@@ -113,6 +114,10 @@ exports.utils = {
113
114
  languageFromHeader: localizeZodIssue_1.languageFromHeader,
114
115
  slugifyTitle: slugifyTitle_1.slugifyTitle,
115
116
  resourceUriFromTitle: resourceUri_1.resourceUriFromTitle,
117
+ accessTokenHint: accessToken_1.accessTokenHint,
118
+ hashAccessToken: accessToken_1.hashAccessToken,
119
+ isAccessToken: accessToken_1.isAccessToken,
120
+ mintAccessToken: accessToken_1.mintAccessToken,
116
121
  TOOL_CATALOG: toolCatalog_1.TOOL_CATALOG,
117
122
  TOOL_KEYS: toolCatalog_1.TOOL_KEYS,
118
123
  describeCatalogTool: toolCatalog_1.describeCatalogTool,
package/dist/schema.d.ts CHANGED
@@ -1255,6 +1255,28 @@ export declare const Schema: {
1255
1255
  userId: z.ZodUUID;
1256
1256
  organizationId: z.ZodUUID;
1257
1257
  }, z.core.$strip>;
1258
+ ACCESS_TOKEN_CREATE: z.ZodObject<{
1259
+ name: z.ZodString;
1260
+ expiresInDays: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
1261
+ userId: z.ZodUUID;
1262
+ organizationId: z.ZodUUID;
1263
+ projectId: z.ZodUUID;
1264
+ }, z.core.$strip>;
1265
+ ACCESS_TOKEN_CREATE_VIEW: z.ZodObject<{
1266
+ name: z.ZodString;
1267
+ expiresInDays: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
1268
+ }, z.core.$strip>;
1269
+ ACCESS_TOKEN_LIST: z.ZodObject<{
1270
+ userId: z.ZodUUID;
1271
+ organizationId: z.ZodUUID;
1272
+ projectId: z.ZodUUID;
1273
+ }, z.core.$strip>;
1274
+ ACCESS_TOKEN_REMOVE: z.ZodObject<{
1275
+ tokenId: z.ZodUUID;
1276
+ userId: z.ZodUUID;
1277
+ organizationId: z.ZodUUID;
1278
+ projectId: z.ZodUUID;
1279
+ }, z.core.$strip>;
1258
1280
  CHANNEL_CONFIG: z.ZodObject<{
1259
1281
  debounceMs: z.ZodOptional<z.ZodNumber>;
1260
1282
  }, z.core.$loose>;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+qBxB,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FrB,CAAC;AAyDN,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;iBAmCpB,CAAC;AAWH,QAAA,MAAM,kBAAkB;;;;;;;;;;iBA+CtB,CAAC;AAiCH,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAapB,CAAC;AAYH,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCxB,CAAC;AA4LH,QAAA,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4DpC,CAAC;AA4BL,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAkDzB,CAAC;AAwGH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsGlB,CAAC;AAGF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAG1E,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAIlE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAMtE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAGtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIvE,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC5C,OAAO,kCAAkC,CAC1C,CAAC;AAKF,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAKD,MAAM,WAAW,0BAA0B;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAC1E;AAMD,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACzC,OAAO,CAAC,EAAE,wBAAwB,EAAE,CAAC;CACtC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA6tBxB,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FrB,CAAC;AAyDN,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;iBAmCpB,CAAC;AAWH,QAAA,MAAM,kBAAkB;;;;;;;;;;iBA+CtB,CAAC;AAiCH,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAapB,CAAC;AAYH,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCxB,CAAC;AA4LH,QAAA,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4DpC,CAAC;AA4BL,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAkDzB,CAAC;AAwGH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0GlB,CAAC;AAGF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAG1E,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAIlE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAMtE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAGtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAIvE,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC5C,OAAO,kCAAkC,CAC1C,CAAC;AAKF,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAKD,MAAM,WAAW,0BAA0B;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAC1E;AAMD,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACzC,OAAO,CAAC,EAAE,wBAAwB,EAAE,CAAC;CACtC"}
package/dist/schema.js CHANGED
@@ -519,6 +519,48 @@ const ORGANIZATION_REMOVE_LLM = zod_1.z.object({
519
519
  userId: zod_1.z.uuid(),
520
520
  organizationId: zod_1.z.uuid()
521
521
  });
522
+ // Personal access tokens. `name` is required rather than optional because it is
523
+ // the only thing anyone has to go on when deciding whether revoking a row will
524
+ // break a deploy, and a list of unnamed credentials is a list nobody prunes.
525
+ //
526
+ // `expiresInDays` is what the caller sends; `expiresAt` is what the row stores.
527
+ // A duration is what someone actually decides ("ninety days"), and computing the
528
+ // date on the server means a clock the client got wrong cannot mint a token that
529
+ // outlives what was asked for. Null is a token that does not expire, which is a
530
+ // real answer for a scheduled deploy and is why it is spelled explicitly rather
531
+ // than reached by leaving the field out.
532
+ const ACCESS_TOKEN_CREATE = zod_1.z.object({
533
+ name: zod_1.z.string().trim().min(1).max(constants_1.constants.ACCESS_TOKEN_NAME_MAX),
534
+ expiresInDays: zod_1.z
535
+ .number()
536
+ .int()
537
+ .min(1)
538
+ .max(constants_1.constants.ACCESS_TOKEN_MAX_EXPIRY_DAYS)
539
+ .nullable()
540
+ .optional(),
541
+ userId: zod_1.z.uuid(),
542
+ organizationId: zod_1.z.uuid(),
543
+ projectId: zod_1.z.uuid()
544
+ });
545
+ const ACCESS_TOKEN_LIST = zod_1.z.object({
546
+ userId: zod_1.z.uuid(),
547
+ organizationId: zod_1.z.uuid(),
548
+ projectId: zod_1.z.uuid()
549
+ });
550
+ const ACCESS_TOKEN_REMOVE = zod_1.z.object({
551
+ tokenId: zod_1.z.uuid(),
552
+ userId: zod_1.z.uuid(),
553
+ organizationId: zod_1.z.uuid(),
554
+ projectId: zod_1.z.uuid()
555
+ });
556
+ // The ids the route already carries come off: the dashboard reads them from the
557
+ // URL it is on, so a form asking for them again is a second place for them to be
558
+ // wrong.
559
+ const ACCESS_TOKEN_CREATE_VIEW = ACCESS_TOKEN_CREATE.omit({
560
+ userId: true,
561
+ organizationId: true,
562
+ projectId: true
563
+ });
522
564
  const ORGANIZATION_CREATE_LLM_VIEW = ORGANIZATION_CREATE_LLM.omit({
523
565
  userId: true,
524
566
  organizationId: true
@@ -1345,6 +1387,10 @@ exports.Schema = {
1345
1387
  ORGANIZATION_UPDATE_LLM,
1346
1388
  ORGANIZATION_UPDATE_LLM_VIEW,
1347
1389
  ORGANIZATION_REMOVE_LLM,
1390
+ ACCESS_TOKEN_CREATE,
1391
+ ACCESS_TOKEN_CREATE_VIEW,
1392
+ ACCESS_TOKEN_LIST,
1393
+ ACCESS_TOKEN_REMOVE,
1348
1394
  CHANNEL_CONFIG,
1349
1395
  CHANNEL_CREATE,
1350
1396
  CHANNEL_CREATE_VIEW,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ganju/utils",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Shared constants, schemas and helpers for Ganju",
5
5
  "license": "Apache-2.0",
6
6
  "author": "MontoyaAndres <andresmontoyafcb@gmail.com>",
@@ -0,0 +1,79 @@
1
+ import { constants } from './constants';
2
+
3
+ /**
4
+ * Minting and recognising a personal access token.
5
+ *
6
+ * The value exists in plaintext exactly once — in the response to the request
7
+ * that created it — and what the database holds is its SHA-256. That is the
8
+ * property the whole credential rests on: a leaked backup, a stray log line, or
9
+ * a support engineer reading the row learns nothing they could present as the
10
+ * token, and there is no path in the product that can print one back, because
11
+ * there is nothing to print.
12
+ *
13
+ * SHA-256 rather than a password hash on purpose. A password is a low-entropy
14
+ * secret a person chose, so the cost of hashing it is what stands between a
15
+ * stolen table and the passwords in it; this is 32 bytes from a CSPRNG, where
16
+ * that cost buys nothing and would be paid on every authenticated request. It
17
+ * is also the hash `oauth_client.client_secret` already uses in this system, so
18
+ * there is one answer here to "how is a machine credential stored".
19
+ */
20
+
21
+ const HINT_SEPARATOR = '…';
22
+
23
+ const base64url = (bytes: Uint8Array): string => {
24
+ let binary = '';
25
+ for (const byte of bytes) binary += String.fromCharCode(byte);
26
+ return btoa(binary)
27
+ .replace(/\+/g, '-')
28
+ .replace(/\//g, '_')
29
+ .replace(/=+$/, '');
30
+ };
31
+
32
+ /** The SHA-256 of a presented token, in the encoding the column stores. */
33
+ export const hashAccessToken = async (token: string): Promise<string> => {
34
+ const digest = await crypto.subtle.digest(
35
+ 'SHA-256',
36
+ new TextEncoder().encode(token)
37
+ );
38
+ return base64url(new Uint8Array(digest));
39
+ };
40
+
41
+ /**
42
+ * Cheap enough to run before the database is touched: a bearer token that does
43
+ * not carry the prefix is an OAuth token, and belongs on the other path.
44
+ */
45
+ export const isAccessToken = (token: string): boolean =>
46
+ token.startsWith(constants.ACCESS_TOKEN_PREFIX);
47
+
48
+ /**
49
+ * What the dashboard shows beside a token's name.
50
+ *
51
+ * Enough to tell two rows apart when someone is deciding which to revoke, and
52
+ * deliberately taken from the *front* of the secret rather than the end: a
53
+ * prefix narrows a brute-force search by exactly as much as a suffix would, and
54
+ * a value people are used to seeing truncated at the end reads as complete when
55
+ * it is the end that is shown.
56
+ */
57
+ export const accessTokenHint = (token: string): string =>
58
+ `${token.slice(
59
+ 0,
60
+ constants.ACCESS_TOKEN_PREFIX.length + constants.ACCESS_TOKEN_HINT_CHARS
61
+ )}${HINT_SEPARATOR}`;
62
+
63
+ export interface MintedAccessToken {
64
+ /** The only time this value exists. Returned to the caller, never stored. */
65
+ token: string;
66
+ tokenHash: string;
67
+ hint: string;
68
+ }
69
+
70
+ export const mintAccessToken = async (): Promise<MintedAccessToken> => {
71
+ const bytes = new Uint8Array(constants.ACCESS_TOKEN_BYTES);
72
+ crypto.getRandomValues(bytes);
73
+ const token = `${constants.ACCESS_TOKEN_PREFIX}${base64url(bytes)}`;
74
+ return {
75
+ token,
76
+ tokenHash: await hashAccessToken(token),
77
+ hint: accessTokenHint(token)
78
+ };
79
+ };
package/src/constants.ts CHANGED
@@ -1695,6 +1695,55 @@ const ARTIFACT_SCOPE_PREFIX = 'artifact:';
1695
1695
  // that is one library's behaviour and this is a login that has already opened
1696
1696
  // someone's browser by the time it would fail.
1697
1697
 
1698
+ // A personal access token — the durable credential a machine with no browser
1699
+ // uses, where an OAuth access token's one hour is not enough. Bound to one
1700
+ // project, because that is the unit a deploy pipeline works on: one repository,
1701
+ // one artifact, one credential in its CI settings.
1702
+ //
1703
+ // The prefix is part of the value rather than decoration: it is what lets the
1704
+ // middleware tell one of these from an OAuth token before it decides which
1705
+ // lookup to make, and it is what secret scanners match on when one leaks into a
1706
+ // repository. The rest is 32 random bytes, base64url — the token is the only
1707
+ // place the value ever exists in plaintext, since what is stored is its hash.
1708
+ const ACCESS_TOKEN_PREFIX = 'ganju_pat_';
1709
+ const ACCESS_TOKEN_BYTES = 32;
1710
+
1711
+ // Enough of the secret to recognise a row by, and not enough to be worth
1712
+ // stealing. Shown in the dashboard and by `ganju token list` beside the name.
1713
+ const ACCESS_TOKEN_HINT_CHARS = 6;
1714
+
1715
+ const ACCESS_TOKEN_NAME_MAX = 100;
1716
+
1717
+ // A ceiling per project, so a compromised session cannot quietly mint an
1718
+ // unbounded set of credentials that each survive the session being ended.
1719
+ const ACCESS_TOKEN_MAX_PER_PROJECT = 20;
1720
+
1721
+ // An expiry is optional, because a scheduled deploy that dies on a date nobody
1722
+ // wrote down is its own kind of outage — but a year is the longest we will
1723
+ // write one for.
1724
+ const ACCESS_TOKEN_MAX_EXPIRY_DAYS = 365;
1725
+
1726
+ // `last_used_at` is a convenience, not an audit log, so it is written at most
1727
+ // this often per token rather than on every request. The question it answers —
1728
+ // "is anything still using this, or can I revoke it" — does not get a better
1729
+ // answer from minute-level precision, and the write would otherwise land on the
1730
+ // hot path of every CI request.
1731
+ const ACCESS_TOKEN_LAST_USED_INTERVAL_MS = 5 * 60 * 1000;
1732
+
1733
+ // The only path a personal access token may reach without naming the project it
1734
+ // is scoped to, and only on GET. `/me` reports who the token is, which is how
1735
+ // the CLI confirms a machine is authenticated at all, and tells it nothing it
1736
+ // does not already hold.
1737
+ //
1738
+ // Everything else is refused, organization routes included — billing, members,
1739
+ // the model configs and the other projects are not what a deploy credential is
1740
+ // for. The list is deliberately this short: a route added later is closed by
1741
+ // omission rather than open by it.
1742
+ const ACCESS_TOKEN_UNSCOPED_PATHS = ['/me'];
1743
+
1744
+ const ACCESS_TOKEN_SCOPE_MESSAGE =
1745
+ 'This token is scoped to a different project';
1746
+
1698
1747
  // Recent custom-tool invocations, as `ganju logs` reads them.
1699
1748
  const CUSTOM_CODE_LOGS_DEFAULT_LIMIT = 20;
1700
1749
  const CUSTOM_CODE_LOGS_MAX_LIMIT = 100;
@@ -2596,6 +2645,15 @@ export const constants = {
2596
2645
  CLI_OAUTH_REDIRECT_PORTS,
2597
2646
  CLI_OAUTH_SCOPES,
2598
2647
  CLI_TOKEN_REFRESH_SKEW_SECONDS,
2648
+ ACCESS_TOKEN_PREFIX,
2649
+ ACCESS_TOKEN_BYTES,
2650
+ ACCESS_TOKEN_HINT_CHARS,
2651
+ ACCESS_TOKEN_NAME_MAX,
2652
+ ACCESS_TOKEN_MAX_PER_PROJECT,
2653
+ ACCESS_TOKEN_MAX_EXPIRY_DAYS,
2654
+ ACCESS_TOKEN_LAST_USED_INTERVAL_MS,
2655
+ ACCESS_TOKEN_UNSCOPED_PATHS,
2656
+ ACCESS_TOKEN_SCOPE_MESSAGE,
2599
2657
  CUSTOM_CODE_LOGS_DEFAULT_LIMIT,
2600
2658
  CUSTOM_CODE_LOGS_MAX_LIMIT,
2601
2659
  BOT_GRANT_TYPE,
package/src/index.ts CHANGED
@@ -135,6 +135,13 @@ import { languageCookieDomain } from './languageCookieDomain';
135
135
  import { localizeZodIssue, languageFromHeader } from './localizeZodIssue';
136
136
  import { slugifyTitle } from './slugifyTitle';
137
137
  import { resourceUriFromTitle } from './resourceUri';
138
+ import {
139
+ accessTokenHint,
140
+ hashAccessToken,
141
+ isAccessToken,
142
+ mintAccessToken
143
+ } from './accessToken';
144
+ import type { MintedAccessToken } from './accessToken';
138
145
  import {
139
146
  TOOL_CATALOG,
140
147
  TOOL_KEYS,
@@ -283,6 +290,10 @@ export const utils = {
283
290
  languageFromHeader,
284
291
  slugifyTitle,
285
292
  resourceUriFromTitle,
293
+ accessTokenHint,
294
+ hashAccessToken,
295
+ isAccessToken,
296
+ mintAccessToken,
286
297
  TOOL_CATALOG,
287
298
  TOOL_KEYS,
288
299
  describeCatalogTool,
@@ -327,6 +338,7 @@ export const utils = {
327
338
  };
328
339
 
329
340
  export type {
341
+ MintedAccessToken,
330
342
  CustomCodeProject,
331
343
  ProjectPathIssue,
332
344
  CatalogGroup,
package/src/schema.ts CHANGED
@@ -603,6 +603,52 @@ const ORGANIZATION_REMOVE_LLM = z.object({
603
603
  organizationId: z.uuid()
604
604
  });
605
605
 
606
+ // Personal access tokens. `name` is required rather than optional because it is
607
+ // the only thing anyone has to go on when deciding whether revoking a row will
608
+ // break a deploy, and a list of unnamed credentials is a list nobody prunes.
609
+ //
610
+ // `expiresInDays` is what the caller sends; `expiresAt` is what the row stores.
611
+ // A duration is what someone actually decides ("ninety days"), and computing the
612
+ // date on the server means a clock the client got wrong cannot mint a token that
613
+ // outlives what was asked for. Null is a token that does not expire, which is a
614
+ // real answer for a scheduled deploy and is why it is spelled explicitly rather
615
+ // than reached by leaving the field out.
616
+ const ACCESS_TOKEN_CREATE = z.object({
617
+ name: z.string().trim().min(1).max(constants.ACCESS_TOKEN_NAME_MAX),
618
+ expiresInDays: z
619
+ .number()
620
+ .int()
621
+ .min(1)
622
+ .max(constants.ACCESS_TOKEN_MAX_EXPIRY_DAYS)
623
+ .nullable()
624
+ .optional(),
625
+ userId: z.uuid(),
626
+ organizationId: z.uuid(),
627
+ projectId: z.uuid()
628
+ });
629
+
630
+ const ACCESS_TOKEN_LIST = z.object({
631
+ userId: z.uuid(),
632
+ organizationId: z.uuid(),
633
+ projectId: z.uuid()
634
+ });
635
+
636
+ const ACCESS_TOKEN_REMOVE = z.object({
637
+ tokenId: z.uuid(),
638
+ userId: z.uuid(),
639
+ organizationId: z.uuid(),
640
+ projectId: z.uuid()
641
+ });
642
+
643
+ // The ids the route already carries come off: the dashboard reads them from the
644
+ // URL it is on, so a form asking for them again is a second place for them to be
645
+ // wrong.
646
+ const ACCESS_TOKEN_CREATE_VIEW = ACCESS_TOKEN_CREATE.omit({
647
+ userId: true,
648
+ organizationId: true,
649
+ projectId: true
650
+ });
651
+
606
652
  const ORGANIZATION_CREATE_LLM_VIEW = ORGANIZATION_CREATE_LLM.omit({
607
653
  userId: true,
608
654
  organizationId: true
@@ -1513,6 +1559,10 @@ export const Schema = {
1513
1559
  ORGANIZATION_UPDATE_LLM,
1514
1560
  ORGANIZATION_UPDATE_LLM_VIEW,
1515
1561
  ORGANIZATION_REMOVE_LLM,
1562
+ ACCESS_TOKEN_CREATE,
1563
+ ACCESS_TOKEN_CREATE_VIEW,
1564
+ ACCESS_TOKEN_LIST,
1565
+ ACCESS_TOKEN_REMOVE,
1516
1566
  CHANNEL_CONFIG,
1517
1567
  CHANNEL_CREATE,
1518
1568
  CHANNEL_CREATE_VIEW,