corsair 0.1.22 → 0.1.24

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.
@@ -6,6 +6,7 @@ import type { AuthTypes } from '../constants';
6
6
  import type { BindEndpoints, EndpointTree } from '../endpoints';
7
7
  import type { CorsairErrorHandler } from '../errors';
8
8
  import type { CorsairInspectMethods } from '../inspect';
9
+ import type { CorsairPermissionsNamespace } from '../permissions';
9
10
  import type { CorsairPlugin } from '../plugins';
10
11
  import type { BindWebhooks, RawWebhookRequest, WebhookTree } from '../webhooks';
11
12
  /**
@@ -102,6 +103,11 @@ export type CorsairTenantWrapper<Plugins extends readonly CorsairPlugin[]> = {
102
103
  * Used to manage secrets shared across all tenants (e.g., OAuth2 client_id, client_secret).
103
104
  */
104
105
  keys: InferAllIntegrationKeys<Plugins>;
106
+ /**
107
+ * Permission management namespace. Use this to query and transition permission records.
108
+ * Available at the root regardless of multi-tenancy setting.
109
+ */
110
+ permissions: CorsairPermissionsNamespace;
105
111
  } & CorsairInspectMethods;
106
112
  /**
107
113
  * Single-tenant client that includes both plugin APIs and integration-level keys.
@@ -112,6 +118,11 @@ export type CorsairSingleTenantClient<Plugins extends readonly CorsairPlugin[]>
112
118
  * Used to manage secrets shared across all tenants (e.g., OAuth2 client_id, client_secret).
113
119
  */
114
120
  keys: InferAllIntegrationKeys<Plugins>;
121
+ /**
122
+ * Permission management namespace. Use this to query and transition permission records.
123
+ * Available at the root regardless of multi-tenancy setting.
124
+ */
125
+ permissions: CorsairPermissionsNamespace;
115
126
  };
116
127
  export type BuildCorsairClientOptions = {
117
128
  database: CorsairDatabase | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/client/index.ts"],"names":[],"mappings":"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"}
@@ -38,7 +38,7 @@ export type { AllProviders, AuthTypes, BaseProviders } from './constants';
38
38
  export type { BindEndpoints, BoundEndpointFn, BoundEndpointTree, CorsairContext, CorsairEndpoint, EndpointPathsOf, EndpointTree, } from './endpoints';
39
39
  export type { CorsairErrorHandler, ErrorContext, ErrorHandler, ErrorHandlerAndMatchFunction, ErrorMatcher, RetryStrategies, RetryStrategy, } from './errors';
40
40
  export type { CorsairInspectMethods, EndpointSchemaResult } from './inspect';
41
- export type { EnforcePermissionOptions, EnforcePermissionResult, } from './permissions';
41
+ export type { CorsairPermissionsNamespace, EnforcePermissionOptions, EnforcePermissionResult, } from './permissions';
42
42
  export type { BeforeHookResult, CorsairIntegration, CorsairKeyBuilder, CorsairKeyBuilderBase, CorsairPlugin, CorsairPluginContext, EndpointHooks, EndpointMetaEntry, EndpointRiskLevel, KeyBuilderContext, PermissionMode, PermissionPolicy, PluginEndpointMeta, PluginPermissionsConfig, RequiredPluginEndpointMeta, RequiredPluginEndpointSchemas, RequiredPluginWebhookSchemas, WebhookHooks, } from './plugins';
43
43
  export type { Bivariant, UnionToIntersection } from './utils';
44
44
  export type { BindWebhooks, BoundWebhook, BoundWebhookTree, CorsairWebhook, CorsairWebhookHandler, CorsairWebhookMatcher, RawWebhookRequest, WebhookPathsOf, WebhookRequest, WebhookResponse, WebhookTree, } from './webhooks';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../core/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../core/index.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { createCorsairDatabase } from '../db/kysely/database';
2
2
  import { createMissingConfigProxy } from './auth/errors';
3
3
  import { buildCorsairClient, buildIntegrationKeys } from './client';
4
4
  import { buildInspectMethods } from './inspect';
5
+ import { buildPermissionsNamespace } from './permissions';
5
6
  // ─────────────────────────────────────────────────────────────────────────────
6
7
  // Internal access for CLI tooling
7
8
  // ─────────────────────────────────────────────────────────────────────────────
@@ -26,6 +27,7 @@ export function createCorsair(config) {
26
27
  multiTenancy: !!config.multiTenancy,
27
28
  approval: config.approval,
28
29
  };
30
+ const permissions = buildPermissionsNamespace(resolvedDatabase);
29
31
  if (config.multiTenancy) {
30
32
  return Object.assign({
31
33
  withTenant: (tenantId) => {
@@ -41,6 +43,7 @@ export function createCorsair(config) {
41
43
  });
42
44
  },
43
45
  keys: integrationKeys,
46
+ permissions,
44
47
  ...buildInspectMethods(config.plugins),
45
48
  }, { [CORSAIR_INTERNAL]: internalConfig });
46
49
  }
@@ -53,6 +56,7 @@ export function createCorsair(config) {
53
56
  });
54
57
  return Object.assign({}, client, {
55
58
  keys: integrationKeys,
59
+ permissions,
56
60
  [CORSAIR_INTERNAL]: internalConfig,
57
61
  });
58
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/inspect/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AA2FnE,KAAK,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAyF5D,MAAM,MAAM,oBAAoB,GAAG;IAClC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IAC7C,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iGAAiG;IACjG,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,OAAO,EAAE;QACR,6EAA6E;QAC7E,SAAS,EAAE;YAAE,IAAI,EAAE,QAAQ,CAAC;YAAC,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACnD;;;WAGG;QACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,IAAI,EAAE,WAAW,CAAC;YAAC,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;KACjE,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,eAAe,CACd,OAAO,CAAC,EAAE,qBAAqB,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC;IAChD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACT,IAAI,EAAE,MAAM,GACV,oBAAoB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;CACrE,CAAC;AAmYF;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,SAAS,aAAa,EAAE,GAC/B,qBAAqB,CASvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/inspect/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AA0FnE,KAAK,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAyF5D,MAAM,MAAM,oBAAoB,GAAG;IAClC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IAC7C,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IACjC,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iGAAiG;IACjG,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAClC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,OAAO,EAAE;QACR,6EAA6E;QAC7E,SAAS,EAAE;YAAE,IAAI,EAAE,QAAQ,CAAC;YAAC,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACnD;;;WAGG;QACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,IAAI,EAAE,WAAW,CAAC;YAAC,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;KACjE,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,eAAe,CACd,OAAO,CAAC,EAAE,qBAAqB,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC;IAChD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,CACT,IAAI,EAAE,MAAM,GACV,oBAAoB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;CACrE,CAAC;AAqYF;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,SAAS,aAAa,EAAE,GAC/B,qBAAqB,CAWvB"}
@@ -1,9 +1,46 @@
1
+ import type { CorsairPermission } from '../../db';
1
2
  import type { CorsairDatabase } from '../../db/kysely/database';
2
3
  import type { EndpointMetaEntry, EndpointRiskLevel, PermissionMode, PermissionPolicy } from '../plugins';
3
4
  /** Resolves the effective permission policy for an endpoint. The override (from permissions.overrides) takes precedence. */
4
5
  export declare function evaluatePermission(riskLevel: EndpointRiskLevel, mode: PermissionMode, override?: PermissionPolicy): PermissionPolicy;
5
6
  /** Parses a duration string ('30s', '10m', '1h', '2h30m', '1d') into milliseconds. */
6
7
  export declare function parseDurationMs(duration: string): number;
8
+ /**
9
+ * The `corsair.permissions` namespace available at the root of every corsair instance.
10
+ * Provides methods for querying and transitioning permission records.
11
+ *
12
+ * Status transitions exposed here are intentionally limited to safe, non-escalating states.
13
+ * Setting a record to 'approved' (which grants execution) is deliberately excluded —
14
+ * that must happen through the out-of-band review flow.
15
+ */
16
+ export type CorsairPermissionsNamespace = {
17
+ /**
18
+ * Fetches a single permission record by its ID.
19
+ * Returns undefined if no record exists or if no database is configured.
20
+ */
21
+ find_by_permission_id(id: string): Promise<CorsairPermission | undefined>;
22
+ /**
23
+ * Fetches a single permission record by its token.
24
+ * The token is the public-facing handle embedded in review URLs.
25
+ * Returns undefined if no record exists or if no database is configured.
26
+ */
27
+ find_by_token(token: string): Promise<CorsairPermission | undefined>;
28
+ /**
29
+ * Marks the permission as 'executing'. Call this when executePermission picks up
30
+ * an approved record and is about to run the endpoint.
31
+ */
32
+ set_executing(id: string): Promise<void>;
33
+ /**
34
+ * Marks the permission as 'completed'. Call this after the endpoint has finished
35
+ * executing successfully.
36
+ */
37
+ set_completed(id: string): Promise<void>;
38
+ };
39
+ /**
40
+ * Builds the `corsair.permissions` namespace for a given database instance.
41
+ * Returns no-op stubs when no database is configured.
42
+ */
43
+ export declare function buildPermissionsNamespace(db: CorsairDatabase | undefined): CorsairPermissionsNamespace;
7
44
  export type EnforcePermissionOptions = {
8
45
  pluginId: string;
9
46
  endpointPath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/permissions/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EACX,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAgBpB,4HAA4H;AAC5H,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,cAAc,EACpB,QAAQ,CAAC,EAAE,gBAAgB,GACzB,gBAAgB,CAGlB;AAMD,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsBxD;AAMD,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,kGAAkG;IAClG,EAAE,CAAC,EAAE,eAAe,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kIAAkI;IAClI,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACrC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,wBAAwB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CA+FlC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/permissions/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EACX,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAgBpB,4HAA4H;AAC5H,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,cAAc,EACpB,QAAQ,CAAC,EAAE,gBAAgB,GACzB,gBAAgB,CAGlB;AAMD,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsBxD;AAMD;;;;;;;GAOG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACzC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IAC1E;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACrE;;;OAGG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,yBAAyB,CACxC,EAAE,EAAE,eAAe,GAAG,SAAS,GAC7B,2BAA2B,CAmC7B;AAMD,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,kGAAkG;IAClG,EAAE,CAAC,EAAE,eAAe,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kIAAkI;IAClI,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACrC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,wBAAwB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CAqGlC"}
@@ -42,6 +42,50 @@ export function parseDurationMs(duration) {
42
42
  }
43
43
  return total > 0 ? total : 10 * 60 * 1_000;
44
44
  }
45
+ /**
46
+ * Builds the `corsair.permissions` namespace for a given database instance.
47
+ * Returns no-op stubs when no database is configured.
48
+ */
49
+ export function buildPermissionsNamespace(db) {
50
+ return {
51
+ async find_by_permission_id(id) {
52
+ if (!db)
53
+ return undefined;
54
+ return db.db
55
+ .selectFrom('corsair_permissions')
56
+ .selectAll()
57
+ .where('id', '=', id)
58
+ .executeTakeFirst();
59
+ },
60
+ async find_by_token(token) {
61
+ if (!db)
62
+ return undefined;
63
+ return db.db
64
+ .selectFrom('corsair_permissions')
65
+ .selectAll()
66
+ .where('token', '=', token)
67
+ .executeTakeFirst();
68
+ },
69
+ async set_executing(id) {
70
+ if (!db)
71
+ return;
72
+ await db.db
73
+ .updateTable('corsair_permissions')
74
+ .set({ status: 'executing', updated_at: new Date() })
75
+ .where('id', '=', id)
76
+ .execute();
77
+ },
78
+ async set_completed(id) {
79
+ if (!db)
80
+ return;
81
+ await db.db
82
+ .updateTable('corsair_permissions')
83
+ .set({ status: 'completed', updated_at: new Date() })
84
+ .where('id', '=', id)
85
+ .execute();
86
+ },
87
+ };
88
+ }
45
89
  /**
46
90
  * Evaluates the permission policy and returns whether the action is allowed.
47
91
  *
@@ -80,7 +124,7 @@ export async function enforcePermission(opts) {
80
124
  .where('args', '=', argsJson)
81
125
  .where('tenant_id', '=', tenantId)
82
126
  .where('expires_at', '>', now)
83
- .where('status', 'in', ['pending', 'approved'])
127
+ .where('status', 'in', ['pending', 'approved', 'executing'])
84
128
  .orderBy('created_at', 'desc')
85
129
  .limit(1)
86
130
  .executeTakeFirst();
@@ -100,6 +144,11 @@ export async function enforcePermission(opts) {
100
144
  },
101
145
  };
102
146
  }
147
+ if (existing.status === 'executing') {
148
+ // executePermission is actively running this — let the endpoint body proceed.
149
+ // Completion is handled by executePermission itself, not via onComplete here.
150
+ return { result: 'allow' };
151
+ }
103
152
  // status === 'pending': already waiting for approval, don't create a duplicate
104
153
  console.log(`[corsair/${opts.pluginId}] '${opts.endpointPath}' blocked — approval already pending.`, `\n Action: ${description}`, `\n Permission ID: ${existing.id}`, `\n Use the token to approve or deny this request.`);
105
154
  return { result: 'blocked' };
@@ -5,21 +5,21 @@ export declare const CorsairIntegrationsSchema: z.ZodObject<{
5
5
  updated_at: z.ZodDate;
6
6
  name: z.ZodString;
7
7
  config: z.ZodEffects<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>, Record<string, unknown>, Record<string, unknown> | null>;
8
- dek: z.ZodOptional<z.ZodString>;
8
+ dek: z.ZodOptional<z.ZodNullable<z.ZodString>>;
9
9
  }, "strip", z.ZodTypeAny, {
10
10
  id: string;
11
11
  created_at: Date;
12
12
  updated_at: Date;
13
13
  name: string;
14
14
  config: Record<string, unknown>;
15
- dek?: string | undefined;
15
+ dek?: string | null | undefined;
16
16
  }, {
17
17
  id: string;
18
18
  created_at: Date;
19
19
  updated_at: Date;
20
20
  name: string;
21
21
  config: Record<string, unknown> | null;
22
- dek?: string | undefined;
22
+ dek?: string | null | undefined;
23
23
  }>;
24
24
  export type CorsairIntegration = z.infer<typeof CorsairIntegrationsSchema>;
25
25
  export declare const CorsairAccountsSchema: z.ZodObject<{
@@ -29,7 +29,7 @@ export declare const CorsairAccountsSchema: z.ZodObject<{
29
29
  tenant_id: z.ZodString;
30
30
  integration_id: z.ZodString;
31
31
  config: z.ZodEffects<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>, Record<string, unknown>, Record<string, unknown> | null>;
32
- dek: z.ZodOptional<z.ZodString>;
32
+ dek: z.ZodOptional<z.ZodNullable<z.ZodString>>;
33
33
  }, "strip", z.ZodTypeAny, {
34
34
  id: string;
35
35
  created_at: Date;
@@ -37,7 +37,7 @@ export declare const CorsairAccountsSchema: z.ZodObject<{
37
37
  config: Record<string, unknown>;
38
38
  tenant_id: string;
39
39
  integration_id: string;
40
- dek?: string | undefined;
40
+ dek?: string | null | undefined;
41
41
  }, {
42
42
  id: string;
43
43
  created_at: Date;
@@ -45,7 +45,7 @@ export declare const CorsairAccountsSchema: z.ZodObject<{
45
45
  config: Record<string, unknown> | null;
46
46
  tenant_id: string;
47
47
  integration_id: string;
48
- dek?: string | undefined;
48
+ dek?: string | null | undefined;
49
49
  }>;
50
50
  export type CorsairAccount = z.infer<typeof CorsairAccountsSchema>;
51
51
  export declare const CorsairEntitiesSchema: z.ZodObject<{
@@ -120,33 +120,37 @@ export declare const CorsairPermissionsSchema: z.ZodObject<{
120
120
  * can scope the corsair instance correctly when executing the approved action.
121
121
  * Defaults to 'default' for single-tenant instances.
122
122
  */
123
- tenant_id: z.ZodOptional<z.ZodString>;
123
+ tenant_id: z.ZodString;
124
124
  /** Current state of the approval request */
125
- status: z.ZodDefault<z.ZodEnum<["pending", "approved", "completed", "denied", "expired"]>>;
125
+ status: z.ZodDefault<z.ZodEnum<["pending", "approved", "executing", "completed", "denied", "expired", "failed"]>>;
126
126
  /** ISO8601 timestamp — when this request becomes invalid */
127
127
  expires_at: z.ZodString;
128
+ /** Stringified error captured when status transitions to 'failed'. Null otherwise. */
129
+ error: z.ZodOptional<z.ZodNullable<z.ZodString>>;
128
130
  }, "strip", z.ZodTypeAny, {
129
131
  id: string;
130
132
  created_at: Date;
131
133
  updated_at: Date;
132
- status: "pending" | "completed" | "approved" | "denied" | "expired";
134
+ status: "pending" | "completed" | "failed" | "approved" | "executing" | "denied" | "expired";
135
+ tenant_id: string;
133
136
  token: string;
134
137
  plugin: string;
135
138
  endpoint: string;
136
139
  args: string;
137
140
  expires_at: string;
138
- tenant_id?: string | undefined;
141
+ error?: string | null | undefined;
139
142
  }, {
140
143
  id: string;
141
144
  created_at: Date;
142
145
  updated_at: Date;
146
+ tenant_id: string;
143
147
  token: string;
144
148
  plugin: string;
145
149
  endpoint: string;
146
150
  args: string;
147
151
  expires_at: string;
148
- status?: "pending" | "completed" | "approved" | "denied" | "expired" | undefined;
149
- tenant_id?: string | undefined;
152
+ status?: "pending" | "completed" | "failed" | "approved" | "executing" | "denied" | "expired" | undefined;
153
+ error?: string | null | undefined;
150
154
  }>;
151
155
  export type CorsairPermission = z.infer<typeof CorsairPermissionsSchema>;
152
156
  export type CorsairPermissionInsert = {
@@ -158,8 +162,9 @@ export type CorsairPermissionInsert = {
158
162
  endpoint: string;
159
163
  args: string;
160
164
  tenant_id?: string;
161
- status?: 'pending' | 'approved' | 'completed' | 'denied' | 'expired';
165
+ status?: 'pending' | 'approved' | 'executing' | 'completed' | 'denied' | 'expired' | 'failed';
162
166
  expires_at: string;
167
+ error?: string | null;
163
168
  };
164
169
  export type CorsairTableName = 'corsair_integrations' | 'corsair_accounts' | 'corsair_entities' | 'corsair_events' | 'corsair_permissions' | (string & {});
165
170
  export type CorsairTableRow = {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../db/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../db/index.ts"],"names":[],"mappings":"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"}
package/dist/db/index.js CHANGED
@@ -4,23 +4,23 @@ import { z } from 'zod';
4
4
  // ─────────────────────────────────────────────────────────────────────────────
5
5
  export const CorsairIntegrationsSchema = z.object({
6
6
  id: z.string(),
7
- created_at: z.date(),
8
- updated_at: z.date(),
7
+ created_at: z.coerce.date(),
8
+ updated_at: z.coerce.date(),
9
9
  name: z.string(),
10
10
  // Coerce DB null to empty object
11
11
  config: z
12
12
  .record(z.unknown())
13
13
  .nullable()
14
14
  .transform((v) => v ?? {}),
15
- dek: z.string().optional(),
15
+ dek: z.string().nullish(),
16
16
  });
17
17
  // ─────────────────────────────────────────────────────────────────────────────
18
18
  // Corsair Accounts
19
19
  // ─────────────────────────────────────────────────────────────────────────────
20
20
  export const CorsairAccountsSchema = z.object({
21
21
  id: z.string(),
22
- created_at: z.date(),
23
- updated_at: z.date(),
22
+ created_at: z.coerce.date(),
23
+ updated_at: z.coerce.date(),
24
24
  tenant_id: z.string(),
25
25
  // references integrations.id
26
26
  integration_id: z.string(),
@@ -29,15 +29,15 @@ export const CorsairAccountsSchema = z.object({
29
29
  .record(z.unknown())
30
30
  .nullable()
31
31
  .transform((v) => v ?? {}),
32
- dek: z.string().optional(),
32
+ dek: z.string().nullish(),
33
33
  });
34
34
  // ─────────────────────────────────────────────────────────────────────────────
35
35
  // Corsair Entities
36
36
  // ─────────────────────────────────────────────────────────────────────────────
37
37
  export const CorsairEntitiesSchema = z.object({
38
38
  id: z.string(),
39
- created_at: z.date(),
40
- updated_at: z.date(),
39
+ created_at: z.coerce.date(),
40
+ updated_at: z.coerce.date(),
41
41
  // references accounts.id (which provides tenant scoping)
42
42
  account_id: z.string(),
43
43
  entity_id: z.string(),
@@ -54,8 +54,8 @@ export const CorsairEntitiesSchema = z.object({
54
54
  // ─────────────────────────────────────────────────────────────────────────────
55
55
  export const CorsairEventsSchema = z.object({
56
56
  id: z.string(),
57
- created_at: z.date(),
58
- updated_at: z.date(),
57
+ created_at: z.coerce.date(),
58
+ updated_at: z.coerce.date(),
59
59
  // references accounts.id (which provides tenant scoping)
60
60
  account_id: z.string(),
61
61
  event_type: z.string(),
@@ -71,8 +71,8 @@ export const CorsairEventsSchema = z.object({
71
71
  // ─────────────────────────────────────────────────────────────────────────────
72
72
  export const CorsairPermissionsSchema = z.object({
73
73
  id: z.string(),
74
- created_at: z.date(),
75
- updated_at: z.date(),
74
+ created_at: z.coerce.date(),
75
+ updated_at: z.coerce.date(),
76
76
  /** 32-byte hex-encoded secure random token, single-use. Embedded in the review URL. */
77
77
  token: z.string(),
78
78
  /** Plugin identifier, e.g. 'github' */
@@ -86,11 +86,21 @@ export const CorsairPermissionsSchema = z.object({
86
86
  * can scope the corsair instance correctly when executing the approved action.
87
87
  * Defaults to 'default' for single-tenant instances.
88
88
  */
89
- tenant_id: z.string().optional(),
89
+ tenant_id: z.string(),
90
90
  /** Current state of the approval request */
91
91
  status: z
92
- .enum(['pending', 'approved', 'completed', 'denied', 'expired'])
92
+ .enum([
93
+ 'pending',
94
+ 'approved',
95
+ 'executing',
96
+ 'completed',
97
+ 'denied',
98
+ 'expired',
99
+ 'failed',
100
+ ])
93
101
  .default('pending'),
94
102
  /** ISO8601 timestamp — when this request becomes invalid */
95
103
  expires_at: z.string(),
104
+ /** Stringified error captured when status transitions to 'failed'. Null otherwise. */
105
+ error: z.string().nullable().optional(),
96
106
  });
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../db/kysely/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,MAAM,EAAkC,MAAM,QAAQ,CAAC;AAChE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EACX,cAAc,EACd,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,qBAAqB,GAAG;IACnC,oBAAoB,EAAE,kBAAkB,CAAC;IACzC,gBAAgB,EAAE,cAAc,CAAC;IACjC,gBAAgB,EAAE,aAAa,CAAC;IAChC,cAAc,EAAE,YAAY,CAAC;IAC7B,mBAAmB,EAAE,iBAAiB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAC9C,mBAAmB,CAAC,UAAU,CAAC,CAC/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC7B,IAAI,GACJ,qBAAqB,GACrB,MAAM,CAAC,qBAAqB,CAAC,CAAC;AA6BjC,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,oBAAoB,GACzB,eAAe,CAsBjB"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../db/kysely/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,MAAM,EAAkC,MAAM,QAAQ,CAAC;AAEhE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EACX,cAAc,EACd,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,qBAAqB,GAAG;IACnC,oBAAoB,EAAE,kBAAkB,CAAC;IACzC,gBAAgB,EAAE,cAAc,CAAC;IACjC,gBAAgB,EAAE,aAAa,CAAC;IAChC,cAAc,EAAE,YAAY,CAAC;IAC7B,mBAAmB,EAAE,iBAAiB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAC9C,mBAAmB,CAAC,UAAU,CAAC,CAC/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC7B,IAAI,GACJ,qBAAqB,GACrB,MAAM,CAAC,qBAAqB,CAAC,CAAC;AA6BjC,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,oBAAoB,GACzB,eAAe,CAuBjB"}
@@ -1,4 +1,5 @@
1
1
  import { Kysely, PostgresDialect, SqliteDialect } from 'kysely';
2
+ import { SqliteDatePlugin } from './sqlite-date-plugin.js';
2
3
  function isPgPool(input) {
3
4
  return (typeof input.query === 'function' &&
4
5
  typeof input.connect === 'function');
@@ -20,6 +21,7 @@ export function createCorsairDatabase(input) {
20
21
  if (isBetterSqlite3(input)) {
21
22
  const db = new Kysely({
22
23
  dialect: new SqliteDialect({ database: input }),
24
+ plugins: [new SqliteDatePlugin()],
23
25
  });
24
26
  return { db };
25
27
  }
@@ -0,0 +1,6 @@
1
+ import { type KyselyPlugin, type PluginTransformQueryArgs, type PluginTransformResultArgs, type QueryResult, type RootOperationNode, type UnknownRow } from 'kysely';
2
+ export declare class SqliteDatePlugin implements KyselyPlugin {
3
+ transformQuery(args: PluginTransformQueryArgs): RootOperationNode;
4
+ transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>>;
5
+ }
6
+ //# sourceMappingURL=sqlite-date-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-date-plugin.d.ts","sourceRoot":"","sources":["../../../db/kysely/sqlite-date-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAE9B,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAEf,MAAM,QAAQ,CAAC;AAwChB,qBAAa,gBAAiB,YAAW,YAAY;IACpD,cAAc,CAAC,IAAI,EAAE,wBAAwB,GAAG,iBAAiB;IAI3D,eAAe,CACpB,IAAI,EAAE,yBAAyB,GAC7B,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;CAGnC"}
@@ -0,0 +1,42 @@
1
+ import { OperationNodeTransformer, } from 'kysely';
2
+ function serializeValue(v) {
3
+ if (v instanceof Date)
4
+ return v.toISOString();
5
+ if (v !== null && typeof v === 'object' && !Buffer.isBuffer(v))
6
+ return JSON.stringify(v);
7
+ return v;
8
+ }
9
+ /**
10
+ * Kysely plugin for SQLite (better-sqlite3) that serializes JavaScript values
11
+ * that the driver cannot bind natively:
12
+ *
13
+ * - Date → ISO 8601 string (better-sqlite3 rejects Date objects)
14
+ * - plain object / array → JSON string (stored as TEXT, read back via parseJsonLike)
15
+ *
16
+ * Handles both ValueNode (WHERE clauses, complex expressions) and
17
+ * PrimitiveValueListNode (INSERT/UPDATE with all-primitive rows — Kysely's
18
+ * performance fast-path that bypasses ValueNode entirely).
19
+ *
20
+ * Applied only to the SQLite Kysely instance in createCorsairDatabase, so it
21
+ * has no effect on Postgres connections.
22
+ */
23
+ class SqliteSerializingTransformer extends OperationNodeTransformer {
24
+ transformValue(node) {
25
+ const serialized = serializeValue(node.value);
26
+ return serialized === node.value ? node : { ...node, value: serialized };
27
+ }
28
+ transformPrimitiveValueList(node) {
29
+ const serialized = node.values.map(serializeValue);
30
+ const changed = serialized.some((v, i) => v !== node.values[i]);
31
+ return changed ? { ...node, values: serialized } : node;
32
+ }
33
+ }
34
+ const transformer = new SqliteSerializingTransformer();
35
+ export class SqliteDatePlugin {
36
+ transformQuery(args) {
37
+ return transformer.transformNode(args.node);
38
+ }
39
+ async transformResult(args) {
40
+ return args.result;
41
+ }
42
+ }
package/dist/db.d.ts CHANGED
@@ -14,5 +14,6 @@
14
14
  */
15
15
  export { sql } from 'kysely';
16
16
  export * from './db/index';
17
+ export { createCorsairDatabase } from './db/kysely/database';
17
18
  export type { CorsairDatabase, CorsairDatabaseInput, CorsairKyselyDatabase, } from './db/kysely/database';
18
19
  //# sourceMappingURL=db.d.ts.map
package/dist/db.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,YAAY,EACX,eAAe,EACf,oBAAoB,EACpB,qBAAqB,GACrB,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EACX,eAAe,EACf,oBAAoB,EACpB,qBAAqB,GACrB,MAAM,sBAAsB,CAAC"}
package/dist/db.js CHANGED
@@ -14,3 +14,4 @@
14
14
  */
15
15
  export { sql } from 'kysely';
16
16
  export * from './db/index';
17
+ export { createCorsairDatabase } from './db/kysely/database';
@@ -1,21 +1,19 @@
1
- import type { CorsairDatabase } from '../db/kysely/database';
1
+ import type { CorsairPermissionsNamespace } from '../core/permissions';
2
2
  /**
3
- * A plugin namespace on the corsair instance that may have API endpoints.
3
+ * The corsair instance type for permission execution.
4
+ * Must expose the `permissions` namespace and optionally a `withTenant` method.
5
+ * The withTenant return type is intentionally broad — we only need to index into it
6
+ * by plugin name, and we cast the result to PluginWithApi at the call site.
4
7
  */
5
- type PluginWithApi = {
6
- api?: Record<string, unknown>;
7
- };
8
- /**
9
- * The corsair instance type for permission execution — a record of plugin namespaces.
10
- * Mirrors the duck-typed shape used by processWebhook.
11
- */
12
- type CorsairInstance = Record<string, PluginWithApi | undefined> & {
13
- withTenant?: (tenantId: string) => CorsairInstance;
8
+ type CorsairInstance = {
9
+ permissions: CorsairPermissionsNamespace;
10
+ withTenant?: (tenantId: string) => Record<string, unknown>;
11
+ [key: string]: unknown;
14
12
  };
15
13
  export type PermissionExecuteResult = {
16
- plugin: string;
17
- endpoint: string;
18
- result: unknown;
14
+ plugin?: string;
15
+ endpoint?: string;
16
+ result?: unknown;
19
17
  error?: string;
20
18
  };
21
19
  /**
@@ -29,19 +27,18 @@ export type PermissionExecuteResult = {
29
27
  * involvement required.
30
28
  *
31
29
  * Lifecycle:
32
- * 1. Fetches the permission record from corsair_permissions
33
- * 2. Validates the record is pending and not expired
30
+ * 1. Fetches the permission record via corsair.permissions.find_by_permission_id
31
+ * 2. Validates the record is approved (human has signed off) and not expired
34
32
  * 3. Resolves the tenant-scoped corsair instance (via withTenant if multi-tenant)
35
- * 4. Sets status to 'approved' so the bound endpoint's permission guard allows it through
33
+ * 4. Sets status to 'executing' via corsair.permissions.set_executing
36
34
  * 5. Navigates corsair[plugin].api[...endpoint path] to find the bound function
37
35
  * 6. Calls the function with the stored args (JSON-parsed)
38
- * 7. The bound function's internal onComplete callback marks the record 'completed'
39
- * 8. Returns the result, or an error object if the endpoint throws
36
+ * 7. Sets status to 'completed' via corsair.permissions.set_completed
37
+ * 8. Returns the result, or an error object if the endpoint gracefully exits
40
38
  *
41
39
  * @param corsair - The corsair instance (returned from createCorsair)
42
- * @param db - The corsair database instance
43
- * @param permissionId - The ID of the corsair_permissions record to execute
40
+ * @param token - The token embedded in the review URL for the corsair_permissions record
44
41
  */
45
- export declare function executePermission(corsair: CorsairInstance, db: CorsairDatabase, permissionId: string): Promise<PermissionExecuteResult>;
42
+ export declare function executePermission(corsair: CorsairInstance, token: string): Promise<PermissionExecuteResult>;
46
43
  export {};
47
44
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../permissions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAM7D;;GAEG;AACH,KAAK,aAAa,GAAG;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B,CAAC;AAEF;;;GAGG;AACH,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC,GAAG;IAClE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,eAAe,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AA4BF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,eAAe,EACxB,EAAE,EAAE,eAAe,EACnB,YAAY,EAAE,MAAM,GAClB,OAAO,CAAC,uBAAuB,CAAC,CAiFlC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../permissions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAcvE;;;;;GAKG;AACH,KAAK,eAAe,GAAG;IACtB,WAAW,EAAE,2BAA2B,CAAC;IACzC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AA4CF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,uBAAuB,CAAC,CAoHlC"}
@@ -1,3 +1,6 @@
1
+ // Internal symbol — mirrors the one exported from core/index.ts without importing it
2
+ // (avoids potential circular dependency) since Symbol.for() uses a global registry.
3
+ const CORSAIR_INTERNAL_SYMBOL = Symbol.for('corsair:internal');
1
4
  // ─────────────────────────────────────────────────────────────────────────────
2
5
  // Helpers
3
6
  // ─────────────────────────────────────────────────────────────────────────────
@@ -16,6 +19,15 @@ function resolveEndpointFn(api, pathParts) {
16
19
  ? current
17
20
  : null;
18
21
  }
22
+ /**
23
+ * Retrieves the internal database from a corsair instance via the CORSAIR_INTERNAL symbol.
24
+ * Used for terminal status transitions (expired, denied) that are not part of the
25
+ * public `corsair.permissions` API.
26
+ */
27
+ function getInternalDb(corsair) {
28
+ const internal = corsair[CORSAIR_INTERNAL_SYMBOL];
29
+ return internal?.database;
30
+ }
19
31
  // ─────────────────────────────────────────────────────────────────────────────
20
32
  // Main Function
21
33
  // ─────────────────────────────────────────────────────────────────────────────
@@ -30,77 +42,105 @@ function resolveEndpointFn(api, pathParts) {
30
42
  * involvement required.
31
43
  *
32
44
  * Lifecycle:
33
- * 1. Fetches the permission record from corsair_permissions
34
- * 2. Validates the record is pending and not expired
45
+ * 1. Fetches the permission record via corsair.permissions.find_by_permission_id
46
+ * 2. Validates the record is approved (human has signed off) and not expired
35
47
  * 3. Resolves the tenant-scoped corsair instance (via withTenant if multi-tenant)
36
- * 4. Sets status to 'approved' so the bound endpoint's permission guard allows it through
48
+ * 4. Sets status to 'executing' via corsair.permissions.set_executing
37
49
  * 5. Navigates corsair[plugin].api[...endpoint path] to find the bound function
38
50
  * 6. Calls the function with the stored args (JSON-parsed)
39
- * 7. The bound function's internal onComplete callback marks the record 'completed'
40
- * 8. Returns the result, or an error object if the endpoint throws
51
+ * 7. Sets status to 'completed' via corsair.permissions.set_completed
52
+ * 8. Returns the result, or an error object if the endpoint gracefully exits
41
53
  *
42
54
  * @param corsair - The corsair instance (returned from createCorsair)
43
- * @param db - The corsair database instance
44
- * @param permissionId - The ID of the corsair_permissions record to execute
55
+ * @param token - The token embedded in the review URL for the corsair_permissions record
45
56
  */
46
- export async function executePermission(corsair, db, permissionId) {
57
+ export async function executePermission(corsair, token) {
47
58
  const now = new Date().toISOString();
48
- const perm = await db.db
49
- .selectFrom('corsair_permissions')
50
- .selectAll()
51
- .where('id', '=', permissionId)
52
- .executeTakeFirst();
53
- if (!perm) {
54
- throw new Error(`executePermission: permission '${permissionId}' not found.`);
59
+ const permission = await corsair.permissions.find_by_token(token);
60
+ if (!permission) {
61
+ console.error(`executePermission: no permission found for token.`);
62
+ return {
63
+ error: `executePermission: no permission found for token.`,
64
+ };
55
65
  }
56
- if (perm.status !== 'pending') {
57
- throw new Error(`executePermission: permission '${permissionId}' is '${perm.status}', expected 'pending'.`);
66
+ if (permission.status !== 'approved') {
67
+ console.error(`executePermission: permission '${permission.id}' is '${permission.status}', expected 'approved'.`);
68
+ return {
69
+ endpoint: permission.endpoint,
70
+ plugin: permission.plugin,
71
+ result: null,
72
+ error: `executePermission: permission '${permission.id}' is '${permission.status}', expected 'approved'.`,
73
+ };
58
74
  }
59
- if (perm.expires_at < now) {
60
- await db.db
61
- .updateTable('corsair_permissions')
62
- .set({ status: 'expired', updated_at: new Date() })
63
- .where('id', '=', permissionId)
64
- .execute();
65
- throw new Error(`executePermission: permission '${permissionId}' has expired.`);
75
+ if (permission.expires_at < now) {
76
+ const db = getInternalDb(corsair);
77
+ if (db) {
78
+ await db.db
79
+ .updateTable('corsair_permissions')
80
+ .set({ status: 'expired', updated_at: new Date() })
81
+ .where('id', '=', permission.id)
82
+ .execute();
83
+ }
84
+ console.error(`executePermission: permission '${permission.id}' has expired.`);
85
+ return {
86
+ error: `executePermission: permission '${permission.id}' has expired.`,
87
+ endpoint: permission.endpoint,
88
+ plugin: permission.plugin,
89
+ result: null,
90
+ };
66
91
  }
67
92
  // Resolve the tenant-scoped instance. The stored tenant_id ensures the correct
68
93
  // plugin context is used for multi-tenant corsair instances.
69
- const tenantId = perm.tenant_id ?? 'default';
94
+ const tenantId = permission.tenant_id ?? 'default';
70
95
  const scopedCorsair = corsair.withTenant
71
96
  ? corsair.withTenant(tenantId)
72
97
  : corsair;
73
- const pluginNamespace = scopedCorsair[perm.plugin];
98
+ const pluginNamespace = scopedCorsair[permission.plugin];
74
99
  if (!pluginNamespace?.api) {
75
- throw new Error(`executePermission: plugin '${perm.plugin}' not found or has no API on this corsair instance.`);
100
+ console.error(`executePermission: plugin '${permission.plugin}' not found or has no API on this corsair instance.`);
101
+ return {
102
+ error: `executePermission: plugin '${permission.plugin}' not found or has no API on this corsair instance.`,
103
+ plugin: permission.plugin,
104
+ endpoint: permission.endpoint,
105
+ result: null,
106
+ };
76
107
  }
77
- const endpointFn = resolveEndpointFn(pluginNamespace.api, perm.endpoint.split('.'));
108
+ const endpointFn = resolveEndpointFn(pluginNamespace.api, permission.endpoint.split('.'));
78
109
  if (!endpointFn) {
79
- throw new Error(`executePermission: endpoint '${perm.endpoint}' not found in plugin '${perm.plugin}'.`);
110
+ console.error(`executePermission: endpoint '${permission.endpoint}' not found in plugin '${permission.plugin}'.`);
111
+ return {
112
+ endpoint: permission.endpoint,
113
+ plugin: permission.plugin,
114
+ result: null,
115
+ error: `executePermission: endpoint '${permission.endpoint}' not found in plugin '${permission.plugin}'.`,
116
+ };
80
117
  }
81
- // Mark as approved — the bound function's enforcePermission will find this record,
82
- // allow the call through, then its onComplete callback marks it 'completed'.
83
- await db.db
84
- .updateTable('corsair_permissions')
85
- .set({ status: 'approved', updated_at: new Date() })
86
- .where('id', '=', permissionId)
87
- .execute();
118
+ // Mark as executing — the bound endpoint's enforcePermission recognises this status
119
+ // and allows the call through. Completion is set explicitly below after the endpoint returns.
120
+ await corsair.permissions.set_executing(permission.id);
88
121
  try {
89
- const result = await endpointFn(JSON.parse(perm.args));
90
- return { plugin: perm.plugin, endpoint: perm.endpoint, result };
122
+ const parsedArgs = typeof permission.args === 'string'
123
+ ? JSON.parse(permission.args)
124
+ : permission.args;
125
+ const result = await endpointFn(parsedArgs);
126
+ await corsair.permissions.set_completed(permission.id);
127
+ return { plugin: permission.plugin, endpoint: permission.endpoint, result };
91
128
  }
92
129
  catch (error) {
93
- // Reset to a terminal state so the approval cannot be silently retried.
94
- await db.db
95
- .updateTable('corsair_permissions')
96
- .set({ status: 'denied', updated_at: new Date() })
97
- .where('id', '=', permissionId)
98
- .execute();
130
+ const errorMessage = error instanceof Error ? error.message : String(error);
131
+ const db = getInternalDb(corsair);
132
+ if (db) {
133
+ await db.db
134
+ .updateTable('corsair_permissions')
135
+ .set({ status: 'failed', error: errorMessage, updated_at: new Date() })
136
+ .where('id', '=', permission.id)
137
+ .execute();
138
+ }
99
139
  return {
100
- plugin: perm.plugin,
101
- endpoint: perm.endpoint,
140
+ plugin: permission.plugin,
141
+ endpoint: permission.endpoint,
102
142
  result: null,
103
- error: error instanceof Error ? error.message : String(error),
143
+ error: errorMessage,
104
144
  };
105
145
  }
106
146
  }
@@ -47,8 +47,8 @@ export declare const ResendWebhookPayloadSchema: z.ZodObject<{
47
47
  created_at: string;
48
48
  name?: string | undefined;
49
49
  status?: string | undefined;
50
- link?: string | undefined;
51
50
  error?: string | undefined;
51
+ link?: string | undefined;
52
52
  subject?: string | undefined;
53
53
  from?: string | undefined;
54
54
  to?: string[] | undefined;
@@ -65,8 +65,8 @@ export declare const ResendWebhookPayloadSchema: z.ZodObject<{
65
65
  created_at: string;
66
66
  name?: string | undefined;
67
67
  status?: string | undefined;
68
- link?: string | undefined;
69
68
  error?: string | undefined;
69
+ link?: string | undefined;
70
70
  subject?: string | undefined;
71
71
  from?: string | undefined;
72
72
  to?: string[] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../plugins/slack/webhooks/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAGxC,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC,SAAS,CAyF5C,CAAC"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../plugins/slack/webhooks/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAGxC,eAAO,MAAM,OAAO,EAAE,aAAa,CAAC,SAAS,CA4F5C,CAAC"}
@@ -43,7 +43,8 @@ export const message = {
43
43
  });
44
44
  corsairEntityId = entity?.id || '';
45
45
  }
46
- else if (!('subtype' in event) || event.subtype !== 'message_deleted') {
46
+ else if (!('subtype' in event) ||
47
+ event.subtype !== 'message_deleted') {
47
48
  // GenericMessageEvent, BotMessageEvent, FileShareMessageEvent, etc.
48
49
  // Skip message_deleted — the message no longer exists and we don't
49
50
  // want to create a spurious record keyed on the deletion-event timestamp.
@@ -1 +1 @@
1
- {"version":3,"file":"tsup.config.d.ts","sourceRoot":"","sources":["../tsup.config.ts"],"names":[],"mappings":";AAEA,wBA6BG"}
1
+ {"version":3,"file":"tsup.config.d.ts","sourceRoot":"","sources":["../tsup.config.ts"],"names":[],"mappings":";AAEA,wBA8BG"}
@@ -18,6 +18,7 @@ export default defineConfig({
18
18
  entry: [
19
19
  'index.ts',
20
20
  'core.ts',
21
+ 'db.ts',
21
22
  'mcp.ts',
22
23
  'orm.ts',
23
24
  'plugins/index.ts',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "corsair",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",