@nocobase/app-plugin-api-keys 0.0.0-stage → 1.0.0-beta.13

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.
Files changed (147) hide show
  1. package/CHANGELOG.md +418 -0
  2. package/README.md +165 -2
  3. package/dist/client/api-keys-client.d.ts +19 -0
  4. package/dist/client/api-keys-client.d.ts.map +1 -0
  5. package/dist/client/api-keys-client.js +7 -0
  6. package/dist/client/api-keys-client.js.map +1 -0
  7. package/dist/client/components/page-container.d.ts +4 -0
  8. package/dist/client/components/page-container.d.ts.map +1 -0
  9. package/dist/client/components/page-container.js +6 -0
  10. package/dist/client/components/page-container.js.map +1 -0
  11. package/dist/client/components/page-header.d.ts +8 -0
  12. package/dist/client/components/page-header.d.ts.map +1 -0
  13. package/dist/client/components/page-header.js +5 -0
  14. package/dist/client/components/page-header.js.map +1 -0
  15. package/dist/client/components/ui/alert-dialog.d.ts +19 -0
  16. package/dist/client/components/ui/alert-dialog.d.ts.map +1 -0
  17. package/dist/client/components/ui/alert-dialog.js +42 -0
  18. package/dist/client/components/ui/alert-dialog.js.map +1 -0
  19. package/dist/client/components/ui/badge.d.ts +6 -0
  20. package/dist/client/components/ui/badge.d.ts.map +1 -0
  21. package/dist/client/components/ui/badge.js +8 -0
  22. package/dist/client/components/ui/badge.js.map +1 -0
  23. package/dist/client/components/ui/button.d.ts +8 -0
  24. package/dist/client/components/ui/button.d.ts.map +1 -0
  25. package/dist/client/components/ui/button.js +27 -0
  26. package/dist/client/components/ui/button.js.map +1 -0
  27. package/dist/client/components/ui/dialog.d.ts +9 -0
  28. package/dist/client/components/ui/dialog.d.ts.map +1 -0
  29. package/dist/client/components/ui/dialog.js +29 -0
  30. package/dist/client/components/ui/dialog.js.map +1 -0
  31. package/dist/client/components/ui/input.d.ts +4 -0
  32. package/dist/client/components/ui/input.d.ts.map +1 -0
  33. package/dist/client/components/ui/input.js +8 -0
  34. package/dist/client/components/ui/input.js.map +1 -0
  35. package/dist/client/components/ui/label.d.ts +3 -0
  36. package/dist/client/components/ui/label.d.ts.map +1 -0
  37. package/dist/client/components/ui/label.js +6 -0
  38. package/dist/client/components/ui/label.js.map +1 -0
  39. package/dist/client/components/ui/select.d.ts +8 -0
  40. package/dist/client/components/ui/select.d.ts.map +1 -0
  41. package/dist/client/components/ui/select.js +19 -0
  42. package/dist/client/components/ui/select.js.map +1 -0
  43. package/dist/client/components/ui/spinner.d.ts +4 -0
  44. package/dist/client/components/ui/spinner.d.ts.map +1 -0
  45. package/dist/client/components/ui/spinner.js +11 -0
  46. package/dist/client/components/ui/spinner.js.map +1 -0
  47. package/dist/client/components/ui/table.d.ts +8 -0
  48. package/dist/client/components/ui/table.d.ts.map +1 -0
  49. package/dist/client/components/ui/table.js +21 -0
  50. package/dist/client/components/ui/table.js.map +1 -0
  51. package/dist/client/expiry.d.ts +23 -0
  52. package/dist/client/expiry.d.ts.map +1 -0
  53. package/dist/client/expiry.js +40 -0
  54. package/dist/client/expiry.js.map +1 -0
  55. package/dist/client/index.d.ts +6 -0
  56. package/dist/client/index.d.ts.map +1 -0
  57. package/dist/client/index.js +7 -0
  58. package/dist/client/index.js.map +1 -0
  59. package/dist/client/lib/utils.d.ts +2 -0
  60. package/dist/client/lib/utils.d.ts.map +1 -0
  61. package/dist/client/lib/utils.js +2 -0
  62. package/dist/client/lib/utils.js.map +1 -0
  63. package/dist/client/locales/en-US.d.ts +71 -0
  64. package/dist/client/locales/en-US.d.ts.map +1 -0
  65. package/dist/client/locales/en-US.js +62 -0
  66. package/dist/client/locales/en-US.js.map +1 -0
  67. package/dist/client/locales/index.d.ts +4 -0
  68. package/dist/client/locales/index.d.ts.map +1 -0
  69. package/dist/client/locales/index.js +7 -0
  70. package/dist/client/locales/index.js.map +1 -0
  71. package/dist/client/locales/zh-CN.d.ts +4 -0
  72. package/dist/client/locales/zh-CN.d.ts.map +1 -0
  73. package/dist/client/locales/zh-CN.js +62 -0
  74. package/dist/client/locales/zh-CN.js.map +1 -0
  75. package/dist/client/pages/api-keys-page.d.ts +3 -0
  76. package/dist/client/pages/api-keys-page.d.ts.map +1 -0
  77. package/dist/client/pages/api-keys-page.js +161 -0
  78. package/dist/client/pages/api-keys-page.js.map +1 -0
  79. package/dist/client/plugin.d.ts +9 -0
  80. package/dist/client/plugin.d.ts.map +1 -0
  81. package/dist/client/plugin.js +10 -0
  82. package/dist/client/plugin.js.map +1 -0
  83. package/dist/client/routes.d.ts +22 -0
  84. package/dist/client/routes.d.ts.map +1 -0
  85. package/dist/client/routes.js +42 -0
  86. package/dist/client/routes.js.map +1 -0
  87. package/dist/database/migrations/.manifest.json +9 -0
  88. package/dist/database/migrations/202609150001_create_api_key_table.js +58 -0
  89. package/dist/database/migrations/202609150001_create_api_key_table.js.map +1 -0
  90. package/dist/server/api-docs.d.ts +24 -0
  91. package/dist/server/api-docs.d.ts.map +1 -0
  92. package/dist/server/api-docs.js +73 -0
  93. package/dist/server/api-docs.js.map +1 -0
  94. package/dist/server/api-keys.d.ts +52 -0
  95. package/dist/server/api-keys.d.ts.map +1 -0
  96. package/dist/server/api-keys.js +199 -0
  97. package/dist/server/api-keys.js.map +1 -0
  98. package/dist/server/index.d.ts +23 -0
  99. package/dist/server/index.d.ts.map +1 -0
  100. package/dist/server/index.js +22 -0
  101. package/dist/server/index.js.map +1 -0
  102. package/dist/server/key-sessions.d.ts +35 -0
  103. package/dist/server/key-sessions.d.ts.map +1 -0
  104. package/dist/server/key-sessions.js +50 -0
  105. package/dist/server/key-sessions.js.map +1 -0
  106. package/dist/server/plugin.d.ts +4 -0
  107. package/dist/server/plugin.d.ts.map +1 -0
  108. package/dist/server/plugin.js +15 -0
  109. package/dist/server/plugin.js.map +1 -0
  110. package/dist/server/providers/index.d.ts +19 -0
  111. package/dist/server/providers/index.d.ts.map +1 -0
  112. package/dist/server/providers/index.js +72 -0
  113. package/dist/server/providers/index.js.map +1 -0
  114. package/dist/server/routes/errors.d.ts +8 -0
  115. package/dist/server/routes/errors.d.ts.map +1 -0
  116. package/dist/server/routes/errors.js +48 -0
  117. package/dist/server/routes/errors.js.map +1 -0
  118. package/dist/server/routes/index.d.ts +10 -0
  119. package/dist/server/routes/index.d.ts.map +1 -0
  120. package/dist/server/routes/index.js +177 -0
  121. package/dist/server/routes/index.js.map +1 -0
  122. package/dist/server/routes/schemas.d.ts +25 -0
  123. package/dist/server/routes/schemas.d.ts.map +1 -0
  124. package/dist/server/routes/schemas.js +127 -0
  125. package/dist/server/routes/schemas.js.map +1 -0
  126. package/dist/server/scoped-keys.d.ts +116 -0
  127. package/dist/server/scoped-keys.d.ts.map +1 -0
  128. package/dist/server/scoped-keys.js +451 -0
  129. package/dist/server/scoped-keys.js.map +1 -0
  130. package/dist/server/scopes.d.ts +70 -0
  131. package/dist/server/scopes.d.ts.map +1 -0
  132. package/dist/server/scopes.js +165 -0
  133. package/dist/server/scopes.js.map +1 -0
  134. package/dist/server/service.d.ts +28 -0
  135. package/dist/server/service.d.ts.map +1 -0
  136. package/dist/server/service.js +69 -0
  137. package/dist/server/service.js.map +1 -0
  138. package/dist/server/tokens.d.ts +6 -0
  139. package/dist/server/tokens.d.ts.map +1 -0
  140. package/dist/server/tokens.js +5 -0
  141. package/dist/server/tokens.js.map +1 -0
  142. package/dist/shared/scopes.d.ts +160 -0
  143. package/dist/shared/scopes.d.ts.map +1 -0
  144. package/dist/shared/scopes.js +83 -0
  145. package/dist/shared/scopes.js.map +1 -0
  146. package/package.json +91 -3
  147. package/skills/nocobase-app-plugin-api-keys/SKILL.md +166 -0
@@ -0,0 +1,22 @@
1
+ import { type AppClientRouteContribution } from '@nocobase/app-client/plugins';
2
+ import type { ApiKeysClientOptions } from './plugin.js';
3
+ export declare const API_KEYS_ROUTE_ID = "@nocobase/app-plugin-api-keys:api-keys";
4
+ /**
5
+ * The permission that opens the page.
6
+ *
7
+ * Keys are self-service — the endpoints behind the page only ever act on the
8
+ * caller's own keys — so an application that wants every signed-in user to
9
+ * manage their own grants `page:api-keys/access` to all authenticated users.
10
+ * It is still declared rather than omitted, so that decision is made in the
11
+ * application's permissions rather than by the absence of a rule.
12
+ */
13
+ export declare const API_KEYS_PAGE_ACCESS: {
14
+ readonly resource: {
15
+ readonly type: "page";
16
+ readonly id: "api-keys";
17
+ };
18
+ readonly action: "access";
19
+ };
20
+ export declare function createApiKeysRoutes(options: ApiKeysClientOptions): AppClientRouteContribution;
21
+ export declare function normalizeApiKeysRoutePath(value: string): string;
22
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../client/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,8BAA8B,CAAC;AAGtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,eAAO,MAAM,iBAAiB,2CAA2C,CAAC;AAE1E;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB;;;;;;CAGvB,CAAC;AAEX,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,GAC5B,0BAA0B,CAa5B;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAY/D"}
@@ -0,0 +1,42 @@
1
+ import { defineSettingsRoutes, } from '@nocobase/app-client/plugins';
2
+ import { KeyRound } from 'lucide-react';
3
+ export const API_KEYS_ROUTE_ID = '@nocobase/app-plugin-api-keys:api-keys';
4
+ /**
5
+ * The permission that opens the page.
6
+ *
7
+ * Keys are self-service — the endpoints behind the page only ever act on the
8
+ * caller's own keys — so an application that wants every signed-in user to
9
+ * manage their own grants `page:api-keys/access` to all authenticated users.
10
+ * It is still declared rather than omitted, so that decision is made in the
11
+ * application's permissions rather than by the absence of a rule.
12
+ */
13
+ export const API_KEYS_PAGE_ACCESS = {
14
+ resource: { type: 'page', id: 'api-keys' },
15
+ action: 'access',
16
+ };
17
+ export function createApiKeysRoutes(options) {
18
+ return defineSettingsRoutes([
19
+ {
20
+ name: 'api-keys',
21
+ path: normalizeApiKeysRoutePath(options.path ?? '/api-keys'),
22
+ authz: API_KEYS_PAGE_ACCESS,
23
+ componentLoader: () => import('./pages/api-keys-page.js'),
24
+ navigation: {
25
+ title: options.title ?? 'nav.apiKeys',
26
+ icon: KeyRound,
27
+ },
28
+ },
29
+ ]);
30
+ }
31
+ export function normalizeApiKeysRoutePath(value) {
32
+ const trimmed = value.trim();
33
+ if (!trimmed || trimmed === '/') {
34
+ throw new TypeError('API keys route path must contain a path segment');
35
+ }
36
+ const path = `/${trimmed.replace(/^\/+|\/+$/g, '')}`;
37
+ if (path === '/settings' || path.startsWith('/settings/')) {
38
+ throw new TypeError('API keys route path is relative to its mount and must not include /settings');
39
+ }
40
+ return path;
41
+ }
42
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../client/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,GAErB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,wCAAwC,CAAC;AAE1E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE;IAC1C,MAAM,EAAE,QAAQ;CACR,CAAC;AAEX,MAAM,UAAU,mBAAmB,CACjC,OAA6B;IAE7B,OAAO,oBAAoB,CAAC;QAC1B;YACE,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,yBAAyB,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;YAC5D,KAAK,EAAE,oBAAoB;YAC3B,eAAe,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,0BAA0B,CAAC;YACzD,UAAU,EAAE;gBACV,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,aAAa;gBACrC,IAAI,EAAE,QAAQ;aACf;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,KAAa;IACrD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CAAC,iDAAiD,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC;IACrD,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,SAAS,CACjB,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 1,
3
+ "files": {
4
+ "202609150001_create_api_key_table.js": {
5
+ "sourceChecksum": "370b04daffda210c32e8a2931944bcd9e4b19938483d75e02f9fbb525fea72d5",
6
+ "artifactChecksum": "270d6f8ec497876bff3aa8d304aa6ad51889b5e5ef632a475e8ca797bd80eb86"
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,58 @@
1
+ import { defineMigration } from '@nocobase/db';
2
+ /**
3
+ * Creates the table the Better Auth API Key plugin reads and writes.
4
+ *
5
+ * The shape is spelled out here rather than derived from the plugin's own
6
+ * schema, so a later release of `@better-auth/api-key` cannot change what this
7
+ * migration did. When that schema gains a field, add it in a new migration.
8
+ *
9
+ * The duration fields are milliseconds held in a 32-bit integer, which caps a
10
+ * refill interval or rate-limit window at roughly 24 days. That is well past
11
+ * the one-day default and keeps every dialect returning a number; a longer
12
+ * window needs a widening migration rather than a value that silently wraps.
13
+ */
14
+ const migration = defineMigration({
15
+ name: '202609150001_create_api_key_table',
16
+ async up({ builder }) {
17
+ await builder.createCollection('apikey', (collection) => {
18
+ collection.string('id', { length: 64 }).notNull();
19
+ collection
20
+ .string('configId', { length: 128 })
21
+ .notNull()
22
+ .defaultTo('default');
23
+ collection.string('name', { length: 255 }).nullable();
24
+ collection.string('prefix', { length: 64 }).nullable();
25
+ // The first few characters, shown in the UI so a listed key is
26
+ // recognizable. `key` itself is a hash and is never displayed.
27
+ collection.string('start', { length: 64 }).nullable();
28
+ collection.string('key', { length: 255 }).notNull();
29
+ collection.string('referenceId', { length: 64 }).notNull();
30
+ collection.integer('refillInterval').nullable();
31
+ collection.integer('refillAmount').nullable();
32
+ collection.datetime('lastRefillAt').nullable();
33
+ collection.boolean('enabled').notNull().defaultTo(true);
34
+ collection.boolean('rateLimitEnabled').notNull().defaultTo(true);
35
+ collection.integer('rateLimitTimeWindow').nullable();
36
+ collection.integer('rateLimitMax').nullable();
37
+ collection.integer('requestCount').notNull().defaultTo(0);
38
+ collection.integer('remaining').nullable();
39
+ collection.datetime('lastRequest').nullable();
40
+ collection.datetime('expiresAt').nullable();
41
+ collection.datetime('createdAt').notNull();
42
+ collection.datetime('updatedAt').notNull();
43
+ collection.text('permissions').nullable();
44
+ collection.text('metadata').nullable();
45
+ collection.primary('id', { name: 'pk_apikey' });
46
+ collection.index('key', { name: 'idx_apikey_key' });
47
+ collection.index('referenceId', { name: 'idx_apikey_reference' });
48
+ collection.index('configId', { name: 'idx_apikey_config' });
49
+ collection.index('expiresAt', { name: 'idx_apikey_expires_at' });
50
+ });
51
+ },
52
+ async down({ builder }) {
53
+ await builder.dropCollection('apikey');
54
+ },
55
+ });
56
+ export default migration;
57
+ //# sourceMappingURL=202609150001_create_api_key_table.js.map
58
+ // @nocobase/task-manifest v1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"202609150001_create_api_key_table.js","sourceRoot":"","sources":["../../../database/migrations/202609150001_create_api_key_table.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Auth } from '@nocobase/app-plugin-authentication/server';
2
+ import type { ApiDocsAccess, ApiDocumentFragment } from '@nocobase/app-server/router';
3
+ /** The security scheme an API key satisfies, in `components.securitySchemes`. */
4
+ export declare const API_KEY_SECURITY_SCHEME = "apiKeyAuth";
5
+ /**
6
+ * Lets a request carrying a valid API key read the API documentation. The key is checked exactly as for any other
7
+ * request — Better Auth resolves it to its owner's session, which refuses a disabled, expired or unknown key and a key
8
+ * whose owner is disabled — but without extending a session, so reading the documentation changes no state.
9
+ *
10
+ * Allows nothing when the application has not configured this package's `apiKey()` Better Auth plugin, or when the
11
+ * request carries no key in the headers that plugin reads.
12
+ */
13
+ export declare function createApiKeyApiDocsAccess(resolveAuth: () => Pick<Auth, 'getSession' | 'plugin'>): ApiDocsAccess;
14
+ /**
15
+ * The API key header as the document's security scheme, `apiKeyAuth`, and a top-level requirement naming it, offered
16
+ * beside the session cookie's: a request carrying either is authenticated. The header is the first one this package's
17
+ * `apiKey()` Better Auth plugin reads a key from, `x-api-key` unless configured. Swagger UI's "Authorize" takes the key
18
+ * and sends it in that header.
19
+ *
20
+ * Contributes nothing when the application has not configured the `apiKey()` plugin, or when no configuration turns
21
+ * keys into sessions through a header, because then no request authenticates with a key.
22
+ */
23
+ export declare function createApiKeySecurityFragment(resolveAuth: () => Pick<Auth, 'plugin'>): ApiDocumentFragment;
24
+ //# sourceMappingURL=api-docs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-docs.d.ts","sourceRoot":"","sources":["../../server/api-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4CAA4C,CAAC;AACvE,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EACpB,MAAM,6BAA6B,CAAC;AAWrC,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,eAAe,CAAC;AAEpD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,QAAQ,CAAC,GACrD,aAAa,CAsBf;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,GACtC,mBAAmB,CAqBrB"}
@@ -0,0 +1,73 @@
1
+ import { APIError } from 'better-auth/api';
2
+ import { findRequestApiKey, requestApiKeyHeaders, } from './api-keys.js';
3
+ const PACKAGE_NAME = '@nocobase/app-plugin-api-keys';
4
+ /** The security scheme an API key satisfies, in `components.securitySchemes`. */
5
+ export const API_KEY_SECURITY_SCHEME = 'apiKeyAuth';
6
+ /**
7
+ * Lets a request carrying a valid API key read the API documentation. The key is checked exactly as for any other
8
+ * request — Better Auth resolves it to its owner's session, which refuses a disabled, expired or unknown key and a key
9
+ * whose owner is disabled — but without extending a session, so reading the documentation changes no state.
10
+ *
11
+ * Allows nothing when the application has not configured this package's `apiKey()` Better Auth plugin, or when the
12
+ * request carries no key in the headers that plugin reads.
13
+ */
14
+ export function createApiKeyApiDocsAccess(resolveAuth) {
15
+ return {
16
+ name: PACKAGE_NAME,
17
+ check: async (context) => {
18
+ const auth = resolveAuth();
19
+ const plugin = auth.plugin('api-key');
20
+ if (!plugin?.options?.configurations)
21
+ return false;
22
+ const headers = context.req.raw.headers;
23
+ const key = findRequestApiKey(plugin, headers);
24
+ if (!key)
25
+ return false;
26
+ try {
27
+ const session = await auth.getSession(headers, {
28
+ disableRefresh: true,
29
+ });
30
+ // Better Auth answers a request carrying a key with the key's session, whose token is the key itself.
31
+ return session?.session.token === key;
32
+ }
33
+ catch (error) {
34
+ if (error instanceof APIError)
35
+ return false;
36
+ throw error;
37
+ }
38
+ },
39
+ };
40
+ }
41
+ /**
42
+ * The API key header as the document's security scheme, `apiKeyAuth`, and a top-level requirement naming it, offered
43
+ * beside the session cookie's: a request carrying either is authenticated. The header is the first one this package's
44
+ * `apiKey()` Better Auth plugin reads a key from, `x-api-key` unless configured. Swagger UI's "Authorize" takes the key
45
+ * and sends it in that header.
46
+ *
47
+ * Contributes nothing when the application has not configured the `apiKey()` plugin, or when no configuration turns
48
+ * keys into sessions through a header, because then no request authenticates with a key.
49
+ */
50
+ export function createApiKeySecurityFragment(resolveAuth) {
51
+ const plugin = resolveAuth().plugin('api-key');
52
+ const [header, ...alternatives] = plugin?.options?.configurations
53
+ ? requestApiKeyHeaders(plugin)
54
+ : [];
55
+ if (!header)
56
+ return { owner: PACKAGE_NAME };
57
+ return {
58
+ owner: PACKAGE_NAME,
59
+ namespace: 'apiKeys',
60
+ components: {
61
+ securitySchemes: {
62
+ [API_KEY_SECURITY_SCHEME]: {
63
+ type: 'apiKey',
64
+ in: 'header',
65
+ name: header,
66
+ description: `An API key issued on the API keys settings page or through \`/api/auth/api-key/create\`. It acts as the user who owns it.${alternatives.length > 0 ? ` The ${alternatives.map((name) => `\`${name}\``).join(', ')} header${alternatives.length > 1 ? 's carry' : ' carries'} it as well.` : ''}`,
67
+ },
68
+ },
69
+ },
70
+ security: [{ [API_KEY_SECURITY_SCHEME]: [] }],
71
+ };
72
+ }
73
+ //# sourceMappingURL=api-docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-docs.js","sourceRoot":"","sources":["../../server/api-docs.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,EACL,iBAAiB,EACjB,oBAAoB,GAErB,MAAM,eAAe,CAAC;AAEvB,MAAM,YAAY,GAAG,+BAA+B,CAAC;AAErD,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,YAAY,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CACvC,WAAsD;IAEtD,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACvB,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAgB,SAAS,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc;gBAAE,OAAO,KAAK,CAAC;YACnD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;YACxC,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/C,IAAI,CAAC,GAAG;gBAAE,OAAO,KAAK,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;oBAC7C,cAAc,EAAE,IAAI;iBACrB,CAAC,CAAC;gBACH,sGAAsG;gBACtG,OAAO,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,GAAG,CAAC;YACxC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,QAAQ;oBAAE,OAAO,KAAK,CAAC;gBAC5C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,4BAA4B,CAC1C,WAAuC;IAEvC,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC,MAAM,CAAgB,SAAS,CAAC,CAAC;IAC9D,MAAM,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,cAAc;QAC/D,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC;QAC9B,CAAC,CAAC,EAAE,CAAC;IACP,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAC5C,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,SAAS,EAAE,SAAS;QACpB,UAAU,EAAE;YACV,eAAe,EAAE;gBACf,CAAC,uBAAuB,CAAC,EAAE;oBACzB,IAAI,EAAE,QAAQ;oBACd,EAAE,EAAE,QAAQ;oBACZ,IAAI,EAAE,MAAM;oBACZ,WAAW,EAAE,4HAA4H,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE;iBAC/S;aACF;SACF;QACD,QAAQ,EAAE,CAAC,EAAE,CAAC,uBAAuB,CAAC,EAAE,EAAE,EAAE,CAAC;KAC9C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { apiKey as betterAuthApiKey, type ApiKeyConfigurationOptions } from '@better-auth/api-key';
2
+ import { createAuthEndpoint } from 'better-auth/api';
3
+ import type { ApiKey } from '@better-auth/api-key';
4
+ type ServerEndpoint<Options extends Parameters<typeof createAuthEndpoint.serverOnly>[0], Result> = ReturnType<typeof createAuthEndpoint.serverOnly<string, Options, Result>>;
5
+ type UpstreamPlugin = ReturnType<typeof betterAuthApiKey>;
6
+ type ManagedQuery = ReturnType<UpstreamPlugin['endpoints']['getApiKey']['options']['query']['partial']>;
7
+ type ManagedBody = UpstreamPlugin['endpoints']['deleteApiKey']['options']['body'];
8
+ /** The configurations the plugin was created with, after this package's defaults are applied. */
9
+ export interface ApiKeysPluginOptions {
10
+ readonly configurations: readonly ApiKeyConfigurationOptions[];
11
+ }
12
+ export type ApiKeysPlugin = Omit<UpstreamPlugin, 'endpoints'> & {
13
+ /** Read by this package's server, for instance to find the key a request carries; Better Auth ignores it. */
14
+ options: ApiKeysPluginOptions;
15
+ endpoints: UpstreamPlugin['endpoints'] & {
16
+ getServerApiKey: ServerEndpoint<{
17
+ method: 'GET';
18
+ query: ManagedQuery;
19
+ }, Omit<ApiKey, 'key'> | null>;
20
+ deleteServerApiKey: ServerEndpoint<{
21
+ method: 'POST';
22
+ body: ManagedBody;
23
+ }, {
24
+ success: boolean;
25
+ }>;
26
+ };
27
+ };
28
+ /**
29
+ * Where the plugin's provider puts the application's own-key policy (`ScopedApiKeys.setOwnKeyPolicy`), so the hook on
30
+ * Better Auth's own `/api-key/create` asks the same question `/api/apiKeys` does.
31
+ */
32
+ export declare const OWN_KEY_POLICY_SLOT: unique symbol;
33
+ export interface OwnKeyPolicySlot {
34
+ current: ((userId: string) => Promise<boolean>) | null;
35
+ }
36
+ /** The slot of a plugin `apiKey()` made, or undefined for any other plugin. */
37
+ export declare function ownKeyPolicySlotOf(plugin: unknown): OwnKeyPolicySlot | undefined;
38
+ /**
39
+ * The API key a request carries, read the way the plugin reads it to authenticate a request: from the header each
40
+ * configuration that turns keys into sessions names, `x-api-key` unless configured. A configuration with a
41
+ * `customAPIKeyGetter` is skipped, because that getter needs a Better Auth endpoint context this caller does not have.
42
+ */
43
+ export declare function findRequestApiKey(plugin: Pick<ApiKeysPlugin, 'options'>, headers: Headers): string | undefined;
44
+ /**
45
+ * The headers a request may carry its API key in, in the order `findRequestApiKey` reads them: those of each
46
+ * configuration that turns keys into sessions, `x-api-key` unless configured, without one that has a
47
+ * `customAPIKeyGetter`.
48
+ */
49
+ export declare function requestApiKeyHeaders(plugin: Pick<ApiKeysPlugin, 'options'>): string[];
50
+ export declare function apiKey(options?: ApiKeyConfigurationOptions | ApiKeyConfigurationOptions[]): ApiKeysPlugin;
51
+ export {};
52
+ //# sourceMappingURL=api-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-keys.d.ts","sourceRoot":"","sources":["../../server/api-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,IAAI,gBAAgB,EAC1B,KAAK,0BAA0B,EAChC,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,kBAAkB,EAGnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD,KAAK,cAAc,CACjB,OAAO,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EACnE,MAAM,IACJ,UAAU,CAAC,OAAO,kBAAkB,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9E,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,KAAK,YAAY,GAAG,UAAU,CAC5B,cAAc,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CACxE,CAAC;AACF,KAAK,WAAW,GACd,cAAc,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AACjE,iGAAiG;AACjG,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,cAAc,EAAE,SAAS,0BAA0B,EAAE,CAAC;CAChE;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG;IAC9D,6GAA6G;IAC7G,OAAO,EAAE,oBAAoB,CAAC;IAC9B,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG;QACvC,eAAe,EAAE,cAAc,CAC7B;YAAE,MAAM,EAAE,KAAK,CAAC;YAAC,KAAK,EAAE,YAAY,CAAA;SAAE,EACtC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,IAAI,CAC3B,CAAC;QACF,kBAAkB,EAAE,cAAc,CAChC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,WAAW,CAAA;SAAE,EACrC;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,CACrB,CAAC;KACH,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,OAAO,MAExC,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;CACxD;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,GACd,gBAAgB,GAAG,SAAS,CAI9B;AA+KD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,EACtC,OAAO,EAAE,OAAO,GACf,MAAM,GAAG,SAAS,CAMpB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,GACrC,MAAM,EAAE,CAUV;AAED,wBAAgB,MAAM,CACpB,OAAO,GAAE,0BAA0B,GAAG,0BAA0B,EAAO,GACtE,aAAa,CAEf"}
@@ -0,0 +1,199 @@
1
+ import { apiKey as betterAuthApiKey, } from '@better-auth/api-key';
2
+ import { isServiceAccount } from '@nocobase/app-plugin-authentication/server';
3
+ import { APIError, createAuthEndpoint, createAuthMiddleware, getSessionFromCtx, } from 'better-auth/api';
4
+ import { isDeviceApprovalPath, isKeyManagementPath } from './key-sessions.js';
5
+ /**
6
+ * Where the plugin's provider puts the application's own-key policy (`ScopedApiKeys.setOwnKeyPolicy`), so the hook on
7
+ * Better Auth's own `/api-key/create` asks the same question `/api/apiKeys` does.
8
+ */
9
+ export const OWN_KEY_POLICY_SLOT = Symbol.for('@nocobase/app-plugin-api-keys/own-key-policy');
10
+ /** The slot of a plugin `apiKey()` made, or undefined for any other plugin. */
11
+ export function ownKeyPolicySlotOf(plugin) {
12
+ if (typeof plugin !== 'object' || plugin === null)
13
+ return undefined;
14
+ return Reflect.get(plugin, OWN_KEY_POLICY_SLOT);
15
+ }
16
+ /**
17
+ * Better Auth's API Key plugin with the defaults a NocoBase application wants.
18
+ *
19
+ * `enableSessionForAPIKeys` is the one that has to be set: Better Auth
20
+ * defaults it off, and with it off a key authenticates nothing — the Settings
21
+ * page still issues keys, and every request carrying one answers 401.
22
+ *
23
+ * Every option is overridable, `enableSessionForAPIKeys` included, so passing
24
+ * all three back reproduces Better Auth's own behaviour exactly.
25
+ */
26
+ function createApiKeysPlugin(options = {}) {
27
+ const configurations = (Array.isArray(options) ? options : [options]).map((configuration) => ({
28
+ enableSessionForAPIKeys: true,
29
+ rateLimit: { enabled: false },
30
+ requireName: true,
31
+ ...configuration,
32
+ }));
33
+ const plugin = betterAuthApiKey(Array.isArray(options) ? configurations : configurations[0]);
34
+ const managedQuery = plugin.endpoints.getApiKey.options.query.partial();
35
+ const managedBody = plugin.endpoints.deleteApiKey.options.body;
36
+ function requireDatabaseConfiguration(configId) {
37
+ const id = configId ?? 'default';
38
+ const config = configurations.find((item) => (item.configId ?? 'default') === id);
39
+ if (!config)
40
+ throw new Error(`API key configuration "${id}" is not registered.`);
41
+ if (config.customStorage ||
42
+ (config.storage && config.storage !== 'database'))
43
+ throw new Error('Server API key management requires the default database schema and storage.');
44
+ return id;
45
+ }
46
+ const headers = [
47
+ ...new Set(configurations.flatMap((configuration) => configuration.apiKeyHeaders === undefined
48
+ ? ['x-api-key']
49
+ : Array.isArray(configuration.apiKeyHeaders)
50
+ ? configuration.apiKeyHeaders
51
+ : [configuration.apiKeyHeaders])),
52
+ ];
53
+ const policy = { current: null };
54
+ const presentedKey = (requestHeaders) => {
55
+ for (const header of headers) {
56
+ const value = requestHeaders?.get(header);
57
+ if (value)
58
+ return value;
59
+ }
60
+ return null;
61
+ };
62
+ const result = {
63
+ ...plugin,
64
+ options: { configurations },
65
+ hooks: {
66
+ ...plugin.hooks,
67
+ before: [
68
+ ...plugin.hooks.before,
69
+ {
70
+ // Runs after Better Auth has turned the key into a session. No key manages keys: every `/api-key/*`
71
+ // endpoint takes a sign-in, and so does approving a device's sign-in (`/device/*`), which issues a session. A scoped key, and any key of a service account, reaches no account endpoint at
72
+ // all: it cannot change the profile, list sessions or sign out either. Only `/get-session` answers, before
73
+ // this hook runs.
74
+ matcher: (ctx) => presentedKey(ctx.headers) !== null,
75
+ handler: createAuthMiddleware(async (ctx) => {
76
+ const key = presentedKey(ctx.headers);
77
+ const session = ctx.context.session;
78
+ if (!key || !session || session.session.token !== key)
79
+ return;
80
+ if (isKeyManagementPath(ctx.path))
81
+ throw APIError.from('FORBIDDEN', {
82
+ code: 'API_KEY_SESSION_FORBIDDEN',
83
+ message: 'API keys are managed only from a signed-in session.',
84
+ });
85
+ if (isDeviceApprovalPath(ctx.path))
86
+ throw APIError.from('FORBIDDEN', {
87
+ code: 'API_KEY_SESSION_FORBIDDEN',
88
+ message: 'A device sign-in is approved only from a signed-in session.',
89
+ });
90
+ let scoped = isServiceAccount(session.user);
91
+ if (!scoped) {
92
+ const row = await ctx.context.adapter.findOne({
93
+ model: 'apikey',
94
+ where: [{ field: 'id', value: session.session.id }],
95
+ });
96
+ scoped = row?.permissions != null;
97
+ }
98
+ if (scoped)
99
+ throw APIError.from('FORBIDDEN', {
100
+ code: 'SCOPED_KEY_FORBIDDEN',
101
+ message: 'A scoped API key or a service-account key cannot use account endpoints.',
102
+ });
103
+ }),
104
+ },
105
+ {
106
+ // A person creating a key of their own from a sign-in: the application may say who may
107
+ // (`ScopedApiKeys.setOwnKeyPolicy`). A server call carries no session and is the caller's to authorize.
108
+ matcher: (ctx) => ctx.path === '/api-key/create',
109
+ handler: createAuthMiddleware(async (ctx) => {
110
+ const check = policy.current;
111
+ if (!check || presentedKey(ctx.headers) !== null)
112
+ return;
113
+ const session = await getSessionFromCtx(ctx);
114
+ if (session && !(await check(session.user.id)))
115
+ throw APIError.from('FORBIDDEN', {
116
+ code: 'API_KEY_CREATION_FORBIDDEN',
117
+ message: 'You may not create API keys of your own.',
118
+ });
119
+ }),
120
+ },
121
+ // The added hooks answer nothing, so they fit the upstream list, whose type names only what Better Auth's hook
122
+ // returns.
123
+ ],
124
+ },
125
+ endpoints: {
126
+ ...plugin.endpoints,
127
+ getServerApiKey: createAuthEndpoint.serverOnly({ method: 'GET', query: managedQuery }, async (ctx) => {
128
+ const configId = requireDatabaseConfiguration(ctx.query.configId);
129
+ if (!ctx.query.id)
130
+ return null;
131
+ const row = await ctx.context.adapter.findOne({
132
+ model: 'apikey',
133
+ where: [
134
+ { field: 'id', value: ctx.query.id },
135
+ { field: 'configId', value: configId },
136
+ ],
137
+ });
138
+ if (!row)
139
+ return null;
140
+ const { key: _hash, ...key } = row;
141
+ return {
142
+ ...key,
143
+ permissions: typeof key.permissions === 'string'
144
+ ? JSON.parse(key.permissions)
145
+ : (key.permissions ?? null),
146
+ };
147
+ }),
148
+ deleteServerApiKey: createAuthEndpoint.serverOnly({ method: 'POST', body: managedBody }, async (ctx) => {
149
+ const configId = requireDatabaseConfiguration(ctx.body.configId);
150
+ await ctx.context.adapter.deleteMany({
151
+ model: 'apikey',
152
+ where: [
153
+ { field: 'id', value: ctx.body.keyId },
154
+ { field: 'configId', value: configId },
155
+ ],
156
+ });
157
+ return { success: true };
158
+ }),
159
+ },
160
+ };
161
+ Object.defineProperty(result, OWN_KEY_POLICY_SLOT, { value: policy });
162
+ return result;
163
+ }
164
+ /**
165
+ * The API key a request carries, read the way the plugin reads it to authenticate a request: from the header each
166
+ * configuration that turns keys into sessions names, `x-api-key` unless configured. A configuration with a
167
+ * `customAPIKeyGetter` is skipped, because that getter needs a Better Auth endpoint context this caller does not have.
168
+ */
169
+ export function findRequestApiKey(plugin, headers) {
170
+ for (const name of requestApiKeyHeaders(plugin)) {
171
+ const value = headers.get(name);
172
+ if (value)
173
+ return value;
174
+ }
175
+ return undefined;
176
+ }
177
+ /**
178
+ * The headers a request may carry its API key in, in the order `findRequestApiKey` reads them: those of each
179
+ * configuration that turns keys into sessions, `x-api-key` unless configured, without one that has a
180
+ * `customAPIKeyGetter`.
181
+ */
182
+ export function requestApiKeyHeaders(plugin) {
183
+ const headers = [];
184
+ for (const configuration of plugin.options.configurations) {
185
+ if (!configuration.enableSessionForAPIKeys)
186
+ continue;
187
+ if (configuration.customAPIKeyGetter)
188
+ continue;
189
+ const names = configuration.apiKeyHeaders ?? 'x-api-key';
190
+ for (const name of Array.isArray(names) ? names : [names])
191
+ if (!headers.includes(name))
192
+ headers.push(name);
193
+ }
194
+ return headers;
195
+ }
196
+ export function apiKey(options = {}) {
197
+ return createApiKeysPlugin(options);
198
+ }
199
+ //# sourceMappingURL=api-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../../server/api-keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export { default } from './plugin.js';
2
+ /**
3
+ * Better Auth's API Key plugin with NocoBase defaults and trusted server operations.
4
+ *
5
+ * It carries Better Auth's name, options, and behaviour, so Better Auth's
6
+ * documentation applies unchanged. It is exported from here rather than
7
+ * installed separately by each application because this package ships the
8
+ * `apikey` table migration, and that table has to match the schema this
9
+ * version of `@better-auth/api-key` declares.
10
+ */
11
+ export { apiKey, findRequestApiKey, OWN_KEY_POLICY_SLOT, ownKeyPolicySlotOf, type ApiKeysPlugin, type ApiKeysPluginOptions, type OwnKeyPolicySlot, } from './api-keys.js';
12
+ export { createApiKeyApiDocsAccess } from './api-docs.js';
13
+ export { API_KEY_ERROR_CODES, API_KEY_TABLE_NAME } from '@better-auth/api-key';
14
+ export type { ApiKey, ApiKeyConfigurationOptions, ApiKeyOptions, } from '@better-auth/api-key';
15
+ export { ApiKeyService, removeUserApiKeys, type ServerApiKeySummary, type CreateServerApiKeyInput, } from './service.js';
16
+ export { ApiKeyScopeError, createApiKeyScopes, type AccessMapping, type MappedAccess, type ApiKeyScopes, type KeyScopeObjectSource, } from './scopes.js';
17
+ export { API_KEY_HEADER, DEVICE_APPROVAL_PATHS, KEY_MANAGEMENT_PATH_PREFIXES, isApiKeySession, isDeviceApprovalPath, isKeyManagementPath, requireSignInSession, } from './key-sessions.js';
18
+ export { ApiKeyRequestError, connectOwnKeyPolicy, DEFAULT_SCOPED_KEY_DAYS, ScopedApiKeys, type ApiKeysConfig, type CheckedApiKey, type OwnKeyPolicy, type ScopedApiKeysOptions, } from './scoped-keys.js';
19
+ export { apiKeyScopesToken, scopedApiKeysToken } from './tokens.js';
20
+ export { API_KEYS_ERROR_DOMAIN, toApiKeysApiError } from './routes/errors.js';
21
+ export { ApiKeysProvider } from './providers/index.js';
22
+ export * from '../shared/scopes.js';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC;;;;;;;;GAQG;AACH,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/E,YAAY,EACV,MAAM,EACN,0BAA0B,EAC1B,aAAa,GACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,GAC7B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,4BAA4B,EAC5B,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,22 @@
1
+ export { default } from './plugin.js';
2
+ /**
3
+ * Better Auth's API Key plugin with NocoBase defaults and trusted server operations.
4
+ *
5
+ * It carries Better Auth's name, options, and behaviour, so Better Auth's
6
+ * documentation applies unchanged. It is exported from here rather than
7
+ * installed separately by each application because this package ships the
8
+ * `apikey` table migration, and that table has to match the schema this
9
+ * version of `@better-auth/api-key` declares.
10
+ */
11
+ export { apiKey, findRequestApiKey, OWN_KEY_POLICY_SLOT, ownKeyPolicySlotOf, } from './api-keys.js';
12
+ export { createApiKeyApiDocsAccess } from './api-docs.js';
13
+ export { API_KEY_ERROR_CODES, API_KEY_TABLE_NAME } from '@better-auth/api-key';
14
+ export { ApiKeyService, removeUserApiKeys, } from './service.js';
15
+ export { ApiKeyScopeError, createApiKeyScopes, } from './scopes.js';
16
+ export { API_KEY_HEADER, DEVICE_APPROVAL_PATHS, KEY_MANAGEMENT_PATH_PREFIXES, isApiKeySession, isDeviceApprovalPath, isKeyManagementPath, requireSignInSession, } from './key-sessions.js';
17
+ export { ApiKeyRequestError, connectOwnKeyPolicy, DEFAULT_SCOPED_KEY_DAYS, ScopedApiKeys, } from './scoped-keys.js';
18
+ export { apiKeyScopesToken, scopedApiKeysToken } from './tokens.js';
19
+ export { API_KEYS_ERROR_DOMAIN, toApiKeysApiError } from './routes/errors.js';
20
+ export { ApiKeysProvider } from './providers/index.js';
21
+ export * from '../shared/scopes.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC;;;;;;;;GAQG;AACH,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GAInB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAO/E,OAAO,EACL,aAAa,EACb,iBAAiB,GAGlB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GAKnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,4BAA4B,EAC5B,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,GAKd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Telling a session made from an API key apart from a sign-in. Managing API keys takes a sign-in: no key, scoped or
3
+ * not, creates, rotates or revokes keys, so a leaked key cannot mint its own successors or remove the evidence. For the
4
+ * same reason no key approves another device's sign-in (Better Auth's device authorization), which issues a session.
5
+ */
6
+ import type { AuthEnv } from '@nocobase/app-plugin-authentication/server';
7
+ import type { MiddlewareHandler } from 'hono';
8
+ /** The header a key arrives in; Better Auth's default `apiKeyHeaders`. */
9
+ export declare const API_KEY_HEADER = "x-api-key";
10
+ /** The Better Auth endpoints no API key may reach, whatever its scope: every `/api-key/*` endpoint. */
11
+ export declare const KEY_MANAGEMENT_PATH_PREFIXES: readonly string[];
12
+ /** Whether a Better Auth endpoint path manages API keys. */
13
+ export declare function isKeyManagementPath(path: string): boolean;
14
+ /**
15
+ * Whether a session was made from an API key: Better Auth's key session carries the key as its token, which a
16
+ * sign-in session never matches.
17
+ */
18
+ export declare function isApiKeySession(session: {
19
+ readonly session: {
20
+ readonly token: string;
21
+ };
22
+ }, headers: Headers, headerNames?: readonly string[]): boolean;
23
+ /**
24
+ * The Better Auth endpoints that review, approve or deny a device authorization (`deviceAuthorization()`): approving
25
+ * issues the device a session, so no API key reaches them.
26
+ */
27
+ export declare const DEVICE_APPROVAL_PATHS: readonly string[];
28
+ /** Whether a Better Auth endpoint path reviews, approves or denies a device authorization. */
29
+ export declare function isDeviceApprovalPath(path: string): boolean;
30
+ /**
31
+ * Refuses a request whose session came from an API key with 403 `API_KEY_SESSION_FORBIDDEN`. Install after
32
+ * `auth.required()` on every route that manages keys, a service account's included.
33
+ */
34
+ export declare function requireSignInSession(): MiddlewareHandler<AuthEnv>;
35
+ //# sourceMappingURL=key-sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-sessions.d.ts","sourceRoot":"","sources":["../../server/key-sessions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4CAA4C,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,0EAA0E;AAC1E,eAAO,MAAM,cAAc,cAAc,CAAC;AAE1C,uGAAuG;AACvG,eAAO,MAAM,4BAA4B,EAAE,SAAS,MAAM,EAAkB,CAAC;AAE7E,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACzD,OAAO,EAAE,OAAO,EAChB,WAAW,GAAE,SAAS,MAAM,EAAqB,GAChD,OAAO,CAKT;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAIlD,CAAC;AAEF,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAejE"}