@authhero/adapter-interfaces 4.5.0 → 4.7.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.
@@ -1,4 +1,4 @@
1
- import { AnalyticsQueryParams, AnalyticsQueryResponse, AnalyticsResource } from "../types/Analytics";
1
+ import { AnalyticsQueryParams, AnalyticsQueryResponse, AnalyticsResource, SessionRetentionParams, SessionRetentionResponse } from "../types/Analytics";
2
2
  export interface AnalyticsAdapter {
3
3
  /**
4
4
  * Run an analytics query for a tenant. The adapter is responsible for
@@ -6,4 +6,11 @@ export interface AnalyticsAdapter {
6
6
  * tenant value from a client-controlled source.
7
7
  */
8
8
  query(tenantId: string, resource: AnalyticsResource, params: AnalyticsQueryParams): Promise<AnalyticsQueryResponse>;
9
+ /**
10
+ * Weekly session cohort retention, computed from the sessions table
11
+ * (created_at_ts × used_at_ts) rather than logs. Optional: adapters that
12
+ * only see log events (e.g. Analytics Engine) cannot implement it, and the
13
+ * route responds 501 when it is absent.
14
+ */
15
+ sessionRetention?(tenantId: string, params: SessionRetentionParams): Promise<SessionRetentionResponse>;
9
16
  }
@@ -72,6 +72,45 @@ export interface AnalyticsQueryResponse {
72
72
  bytes_read?: number;
73
73
  };
74
74
  }
75
+ export interface SessionRetentionParams {
76
+ /** Number of weekly cohorts to include, counting back from the current week */
77
+ weeks: number;
78
+ }
79
+ export interface SessionRetentionCohort {
80
+ /** ISO date (UTC Monday) the cohort week starts on */
81
+ cohort: string;
82
+ /** Sessions created during the cohort week */
83
+ sessions: number;
84
+ /**
85
+ * active[k] = sessions still active k weeks after the cohort week, i.e.
86
+ * last used during week k or later. active[0] === sessions. The array is
87
+ * truncated at the current week, so recent cohorts have fewer entries.
88
+ */
89
+ active: number[];
90
+ }
91
+ export interface SessionRetentionResponse {
92
+ interval: "week";
93
+ /** Inclusive lower bound of the first cohort week */
94
+ from: string;
95
+ /** Timestamp the query ran at; the last cohort week is still in progress */
96
+ to: string;
97
+ cohorts: SessionRetentionCohort[];
98
+ }
99
+ export declare const sessionRetentionCohortSchema: z.ZodObject<{
100
+ cohort: z.ZodString;
101
+ sessions: z.ZodNumber;
102
+ active: z.ZodArray<z.ZodNumber>;
103
+ }, z.core.$strip>;
104
+ export declare const sessionRetentionResponseSchema: z.ZodObject<{
105
+ interval: z.ZodLiteral<"week">;
106
+ from: z.ZodString;
107
+ to: z.ZodString;
108
+ cohorts: z.ZodArray<z.ZodObject<{
109
+ cohort: z.ZodString;
110
+ sessions: z.ZodNumber;
111
+ active: z.ZodArray<z.ZodNumber>;
112
+ }, z.core.$strip>>;
113
+ }, z.core.$strip>;
75
114
  export declare const analyticsColumnMetaSchema: z.ZodObject<{
76
115
  name: z.ZodString;
77
116
  type: z.ZodString;
@@ -9,6 +9,9 @@ export declare const connectionOptionsSchema: z.ZodObject<{
9
9
  client_secret: z.ZodOptional<z.ZodString>;
10
10
  app_secret: z.ZodOptional<z.ZodString>;
11
11
  scope: z.ZodOptional<z.ZodString>;
12
+ client_secret_hint: z.ZodOptional<z.ZodString>;
13
+ app_secret_hint: z.ZodOptional<z.ZodString>;
14
+ twilio_token_hint: z.ZodOptional<z.ZodString>;
12
15
  authorization_endpoint: z.ZodOptional<z.ZodString>;
13
16
  token_endpoint: z.ZodOptional<z.ZodString>;
14
17
  userinfo_endpoint: z.ZodOptional<z.ZodString>;
@@ -55,6 +58,7 @@ export declare const connectionOptionsSchema: z.ZodObject<{
55
58
  userinfo_endpoint: z.ZodOptional<z.ZodString>;
56
59
  client_id: z.ZodOptional<z.ZodString>;
57
60
  client_secret: z.ZodOptional<z.ZodString>;
61
+ client_secret_hint: z.ZodOptional<z.ZodString>;
58
62
  realm: z.ZodOptional<z.ZodString>;
59
63
  }, z.core.$strip>>;
60
64
  attributes: z.ZodOptional<z.ZodObject<{
@@ -160,6 +164,9 @@ export declare const connectionInsertSchema: z.ZodObject<{
160
164
  client_secret: z.ZodOptional<z.ZodString>;
161
165
  app_secret: z.ZodOptional<z.ZodString>;
162
166
  scope: z.ZodOptional<z.ZodString>;
167
+ client_secret_hint: z.ZodOptional<z.ZodString>;
168
+ app_secret_hint: z.ZodOptional<z.ZodString>;
169
+ twilio_token_hint: z.ZodOptional<z.ZodString>;
163
170
  authorization_endpoint: z.ZodOptional<z.ZodString>;
164
171
  token_endpoint: z.ZodOptional<z.ZodString>;
165
172
  userinfo_endpoint: z.ZodOptional<z.ZodString>;
@@ -206,6 +213,7 @@ export declare const connectionInsertSchema: z.ZodObject<{
206
213
  userinfo_endpoint: z.ZodOptional<z.ZodString>;
207
214
  client_id: z.ZodOptional<z.ZodString>;
208
215
  client_secret: z.ZodOptional<z.ZodString>;
216
+ client_secret_hint: z.ZodOptional<z.ZodString>;
209
217
  realm: z.ZodOptional<z.ZodString>;
210
218
  }, z.core.$strip>>;
211
219
  attributes: z.ZodOptional<z.ZodObject<{
@@ -322,6 +330,9 @@ export declare const connectionSchema: z.ZodObject<{
322
330
  client_secret: z.ZodOptional<z.ZodString>;
323
331
  app_secret: z.ZodOptional<z.ZodString>;
324
332
  scope: z.ZodOptional<z.ZodString>;
333
+ client_secret_hint: z.ZodOptional<z.ZodString>;
334
+ app_secret_hint: z.ZodOptional<z.ZodString>;
335
+ twilio_token_hint: z.ZodOptional<z.ZodString>;
325
336
  authorization_endpoint: z.ZodOptional<z.ZodString>;
326
337
  token_endpoint: z.ZodOptional<z.ZodString>;
327
338
  userinfo_endpoint: z.ZodOptional<z.ZodString>;
@@ -368,6 +379,7 @@ export declare const connectionSchema: z.ZodObject<{
368
379
  userinfo_endpoint: z.ZodOptional<z.ZodString>;
369
380
  client_id: z.ZodOptional<z.ZodString>;
370
381
  client_secret: z.ZodOptional<z.ZodString>;
382
+ client_secret_hint: z.ZodOptional<z.ZodString>;
371
383
  realm: z.ZodOptional<z.ZodString>;
372
384
  }, z.core.$strip>>;
373
385
  attributes: z.ZodOptional<z.ZodObject<{
@@ -1,4 +1,25 @@
1
1
  import { z } from "@hono/zod-openapi";
2
+ /**
3
+ * Triggers the given stored hook is allowed to run on, or `undefined` when the
4
+ * value isn't a recognisable hook.
5
+ *
6
+ * Needed because the update path validates a union of *partial* variant
7
+ * schemas: a body carrying only `trigger_id` matches whichever member has no
8
+ * other required field left, so the stored hook's type is invisible to the
9
+ * request validator. Callers re-check the incoming trigger against the row
10
+ * they're about to modify.
11
+ */
12
+ export declare function allowedTriggersForHook(hook: unknown): readonly string[] | undefined;
13
+ /**
14
+ * Built-in universal-login pages a page hook can interrupt the login with.
15
+ * The runtime redirects to `/u/{page_id}` (or `/u2/{page_id}`), so this enum
16
+ * is the allowlist of interstitial screens — a free-form string would let a
17
+ * misconfigured hook bounce logins to an arbitrary universal-login path.
18
+ */
19
+ export declare const hookPageId: z.ZodEnum<{
20
+ impersonate: "impersonate";
21
+ }>;
22
+ export type HookPageId = z.infer<typeof hookPageId>;
2
23
  export declare const hookTemplateId: z.ZodEnum<{
3
24
  "ensure-username": "ensure-username";
4
25
  "set-preferred-username": "set-preferred-username";
@@ -34,12 +55,7 @@ export declare const hookInsertSchema: z.ZodUnion<readonly [z.ZodObject<{
34
55
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
35
56
  }, z.core.$strip>, z.ZodObject<{
36
57
  trigger_id: z.ZodEnum<{
37
- "pre-user-registration": "pre-user-registration";
38
- "post-user-registration": "post-user-registration";
39
58
  "post-user-login": "post-user-login";
40
- "validate-registration-username": "validate-registration-username";
41
- "pre-user-deletion": "pre-user-deletion";
42
- "post-user-deletion": "post-user-deletion";
43
59
  }>;
44
60
  form_id: z.ZodString;
45
61
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -77,6 +93,19 @@ export declare const hookInsertSchema: z.ZodUnion<readonly [z.ZodObject<{
77
93
  priority: z.ZodOptional<z.ZodNumber>;
78
94
  hook_id: z.ZodOptional<z.ZodString>;
79
95
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
96
+ }, z.core.$strip>, z.ZodObject<{
97
+ trigger_id: z.ZodEnum<{
98
+ "post-user-login": "post-user-login";
99
+ }>;
100
+ page_id: z.ZodEnum<{
101
+ impersonate: "impersonate";
102
+ }>;
103
+ permission_required: z.ZodOptional<z.ZodString>;
104
+ enabled: z.ZodDefault<z.ZodBoolean>;
105
+ synchronous: z.ZodDefault<z.ZodBoolean>;
106
+ priority: z.ZodOptional<z.ZodNumber>;
107
+ hook_id: z.ZodOptional<z.ZodString>;
108
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
80
109
  }, z.core.$strip>]>;
81
110
  export type HookInsert = z.infer<typeof hookInsertSchema>;
82
111
  export declare const hookSchema: z.ZodUnion<readonly [z.ZodObject<{
@@ -99,12 +128,7 @@ export declare const hookSchema: z.ZodUnion<readonly [z.ZodObject<{
99
128
  url: z.ZodString;
100
129
  }, z.core.$strip>, z.ZodObject<{
101
130
  trigger_id: z.ZodEnum<{
102
- "pre-user-registration": "pre-user-registration";
103
- "post-user-registration": "post-user-registration";
104
131
  "post-user-login": "post-user-login";
105
- "validate-registration-username": "validate-registration-username";
106
- "pre-user-deletion": "pre-user-deletion";
107
- "post-user-deletion": "post-user-deletion";
108
132
  }>;
109
133
  enabled: z.ZodDefault<z.ZodBoolean>;
110
134
  synchronous: z.ZodDefault<z.ZodBoolean>;
@@ -148,5 +172,20 @@ export declare const hookSchema: z.ZodUnion<readonly [z.ZodObject<{
148
172
  updated_at: z.ZodString;
149
173
  hook_id: z.ZodString;
150
174
  code_id: z.ZodString;
175
+ }, z.core.$strip>, z.ZodObject<{
176
+ trigger_id: z.ZodEnum<{
177
+ "post-user-login": "post-user-login";
178
+ }>;
179
+ enabled: z.ZodDefault<z.ZodBoolean>;
180
+ synchronous: z.ZodDefault<z.ZodBoolean>;
181
+ priority: z.ZodOptional<z.ZodNumber>;
182
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
183
+ created_at: z.ZodString;
184
+ updated_at: z.ZodString;
185
+ hook_id: z.ZodString;
186
+ page_id: z.ZodEnum<{
187
+ impersonate: "impersonate";
188
+ }>;
189
+ permission_required: z.ZodOptional<z.ZodString>;
151
190
  }, z.core.$strip>]>;
152
191
  export type Hook = z.infer<typeof hookSchema>;
@@ -8,3 +8,4 @@ export * from "./base32";
8
8
  export * from "./hex";
9
9
  export * from "./cursor";
10
10
  export * from "./lucene";
11
+ export * from "./session-retention";
@@ -0,0 +1,32 @@
1
+ import { SessionRetentionResponse } from "../types/Analytics";
2
+ export declare const WEEK_MS: number;
3
+ /**
4
+ * The Unix epoch (1970-01-01) was a Thursday; adding 3 days before dividing
5
+ * by a week aligns bucket boundaries to Monday 00:00 UTC.
6
+ */
7
+ export declare const MONDAY_EPOCH_SHIFT_MS: number;
8
+ /** Monday-aligned week index for an epoch-ms timestamp. */
9
+ export declare function weekIndex(epochMs: number): number;
10
+ /** Epoch ms of the UTC Monday a week index starts on. */
11
+ export declare function weekStartMs(week: number): number;
12
+ export interface SessionRetentionWindow {
13
+ currentWeek: number;
14
+ firstWeek: number;
15
+ /** Epoch ms lower bound for created_at_ts — the start of the first cohort week */
16
+ sinceMs: number;
17
+ }
18
+ export declare function sessionRetentionWindow(weeks: number, now?: number): SessionRetentionWindow;
19
+ export interface SessionRetentionRawRow {
20
+ /** Monday-aligned week index the session was created in */
21
+ created_week: number;
22
+ /** Monday-aligned week index the session was last used in */
23
+ used_week: number;
24
+ count: number;
25
+ }
26
+ /**
27
+ * Fold raw (created-week × last-used-week) counts into per-cohort retention.
28
+ * A session counts as active k weeks after its cohort week when it was last
29
+ * used during that week or any later one, so a single last-used timestamp is
30
+ * enough to reconstruct the whole retention triangle.
31
+ */
32
+ export declare function buildSessionRetention(rows: SessionRetentionRawRow[], weeks: number, now?: number): SessionRetentionResponse;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "https://github.com/markusahlstrand/authhero"
13
13
  },
14
- "version": "4.5.0",
14
+ "version": "4.7.0",
15
15
  "files": [
16
16
  "dist"
17
17
  ],