@authhero/kysely-adapter 11.18.1 → 11.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ import { Kysely } from "kysely";
2
+ /**
3
+ * Registry of per-tenant control-plane-communication PUBLIC keys (issue #1139).
4
+ *
5
+ * Each WFP tenant shard is provisioned a dedicated keypair: the private half
6
+ * becomes the shard's `CONTROL_PLANE_COMM_KEY` secret and signs only its
7
+ * write-through calls (custom domains, tenant members) — never the tenant's
8
+ * user tokens. The public half lives here so the control plane's verifier
9
+ * resolves it locally, with no reach back to the shard.
10
+ *
11
+ * A table rather than KV: the control plane must verify a shard's token
12
+ * immediately after provisioning, and an eventually-consistent store yields
13
+ * transient `unknown kid` failures inside the propagation window.
14
+ *
15
+ * `kid` is the primary key — verification resolves a key by `kid` and rotation
16
+ * mints a new one, so several live rows per tenant are expected (a token signed
17
+ * with the prior key must still verify during a swap).
18
+ *
19
+ * No FK to `tenants`, for the same reason as `tenant_operations`: cleanup is a
20
+ * deprovision concern, and an orphaned public key is inert — it can only verify
21
+ * a token whose private half nothing holds.
22
+ *
23
+ * `public_jwk` holds the full JWK JSON including `kid` + `alg`
24
+ * (`crypto.subtle.exportKey("jwk")` omits both, so the producer must stamp
25
+ * them; the verifier matches on `kid` and rejects on `alg` mismatch).
26
+ */
27
+ export declare function up(db: Kysely<unknown>): Promise<void>;
28
+ export declare function down(db: Kysely<unknown>): Promise<void>;
@@ -0,0 +1,4 @@
1
+ import { Kysely } from "kysely";
2
+ import { Database } from "../../src/db";
3
+ export declare function up(db: Kysely<Database>): Promise<void>;
4
+ export declare function down(db: Kysely<Database>): Promise<void>;
@@ -177,6 +177,8 @@ import * as o078_tenant_database_version from "./2026-06-27T12:00:00_tenant_data
177
177
  import * as o079_user_activity_and_user_column_cleanup from "./2026-06-30T12:00:00_user_activity_and_user_column_cleanup";
178
178
  import * as o080_drop_user_activity_columns_from_users from "./2026-07-02T12:00:00_drop_user_activity_columns_from_users";
179
179
  import * as o081_tenant_operations from "./2026-07-04T12:00:00_tenant_operations";
180
+ import * as o082_control_plane_comm_keys from "./2026-07-16T10:00:00_control_plane_comm_keys";
181
+ import * as o083_codes_expires_at_ts from "./2026-07-16T12:00:00_codes_expires_at_ts";
180
182
  declare const _default: {
181
183
  m1_init: typeof m1_init;
182
184
  m2_magicLink: typeof m2_magicLink;
@@ -357,5 +359,7 @@ declare const _default: {
357
359
  o079_user_activity_and_user_column_cleanup: typeof o079_user_activity_and_user_column_cleanup;
358
360
  o080_drop_user_activity_columns_from_users: typeof o080_drop_user_activity_columns_from_users;
359
361
  o081_tenant_operations: typeof o081_tenant_operations;
362
+ o082_control_plane_comm_keys: typeof o082_control_plane_comm_keys;
363
+ o083_codes_expires_at_ts: typeof o083_codes_expires_at_ts;
360
364
  };
361
365
  export default _default;
@@ -0,0 +1,3 @@
1
+ import { Kysely } from "kysely";
2
+ import { Database } from "../db";
3
+ export declare function cleanupCodes(db: Kysely<Database>): (olderThan: string) => Promise<number>;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Convert a code's ISO-8601 `expires_at` into the numeric `expires_at_ts` twin.
3
+ *
4
+ * `Code.expires_at` is only typed as `z.string()`, so an unparseable value is
5
+ * representable. `Date.getTime()` would return NaN for it, which fails against
6
+ * the bigint column. Treat it as already expired (0) instead: such a code is
7
+ * unusable anyway, and 0 keeps it sweepable rather than stranding it in the
8
+ * table forever. The migration's backfill applies the same rule.
9
+ */
10
+ export declare function toExpiresAtTs(expiresAt: string): number;
@@ -836,6 +836,7 @@ export interface Database {
836
836
  client_registration_tokens: z.infer<typeof sqlClientRegistrationTokenSchema>;
837
837
  codes: Code & {
838
838
  tenant_id: string;
839
+ expires_at_ts?: number | null;
839
840
  };
840
841
  connections: z.infer<typeof sqlConnectionSchema>;
841
842
  custom_domains: z.infer<typeof sqlCustomDomainSchema>;
@@ -15,10 +15,14 @@ import { ListParams } from "@authhero/adapter-interfaces";
15
15
  */
16
16
  export declare function isKeysetRequest(params?: ListParams): boolean;
17
17
  export interface KeysetOptions {
18
- /** Column to sort by. Must be a real column on the queried table. */
18
+ /**
19
+ * Column to sort by. Must be a real column on the queried table. May be
20
+ * table-qualified (`users.created_at`) when the query joins other tables;
21
+ * the row property is read from the segment after the last dot.
22
+ */
19
23
  sortColumn: string;
20
24
  sortOrder: "asc" | "desc";
21
- /** Unique tiebreaker column; defaults to "id". */
25
+ /** Unique tiebreaker column (may be table-qualified); defaults to "id". */
22
26
  idColumn?: string;
23
27
  /**
24
28
  * Sort spec (e.g. `date:desc`) for endpoints that honor a caller-chosen sort