@aooth/auth 0.1.7 → 0.1.9

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,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_payload = require("./payload-BJjvj8AH.cjs");
2
3
  let node_crypto = require("node:crypto");
3
4
  //#region src/atscript-db/index.ts
4
5
  /**
@@ -22,18 +23,7 @@ var CredentialStoreAtscriptDb = class {
22
23
  async persist(state, ttl) {
23
24
  const token = (0, node_crypto.randomUUID)();
24
25
  const expiresAt = typeof ttl === "number" ? Date.now() + ttl : state.expiresAt;
25
- const row = {
26
- token,
27
- userId: state.userId,
28
- issuedAt: state.issuedAt,
29
- expiresAt,
30
- kind: state.kind,
31
- claims: state.claims,
32
- metadata: state.metadata,
33
- parentCredentialId: state.parentCredentialId,
34
- rotatedAt: state.rotatedAt
35
- };
36
- await this.table.insertOne(row);
26
+ await this.table.insertOne(stateToRow(state, token, expiresAt));
37
27
  return token;
38
28
  }
39
29
  async retrieve(token) {
@@ -57,23 +47,21 @@ var CredentialStoreAtscriptDb = class {
57
47
  await this.revoke(token);
58
48
  return token;
59
49
  }
60
- const row = {
61
- token,
62
- userId: state.userId,
63
- issuedAt: state.issuedAt,
64
- expiresAt: state.expiresAt,
65
- kind: state.kind,
66
- claims: state.claims,
67
- metadata: state.metadata,
68
- parentCredentialId: state.parentCredentialId,
69
- rotatedAt: state.rotatedAt
70
- };
71
- await this.table.replaceOne(row);
50
+ await this.table.replaceOne(stateToRow(state, token, state.expiresAt));
72
51
  return token;
73
52
  }
74
53
  async revoke(token) {
75
54
  await this.table.deleteOne(token);
76
55
  }
56
+ async touch(token, at) {
57
+ const row = await this.table.findOne({ filter: { token } });
58
+ if (!row) return;
59
+ if (row.expiresAt <= Date.now()) return;
60
+ await this.table.replaceOne({
61
+ ...row,
62
+ lastSeenAt: at
63
+ });
64
+ }
77
65
  async revokeAllForUser(userId) {
78
66
  return (await this.table.deleteMany({ userId })).deletedCount;
79
67
  }
@@ -96,17 +84,40 @@ var CredentialStoreAtscriptDb = class {
96
84
  return out;
97
85
  }
98
86
  };
87
+ /**
88
+ * Build the persisted row from a credential state: typed payload columns first
89
+ * (so an envelope field wins a name clash), then the fixed envelope fields and
90
+ * the resolved `token` + `expiresAt`. Shared by `persist` and `update`, which
91
+ * differ only in the `expiresAt` they resolve.
92
+ */
93
+ function stateToRow(state, token, expiresAt) {
94
+ return {
95
+ ...require_payload.credentialPayloadOf(state),
96
+ token,
97
+ userId: state.userId,
98
+ issuedAt: state.issuedAt,
99
+ expiresAt,
100
+ kind: state.kind,
101
+ metadata: state.metadata,
102
+ parentCredentialId: state.parentCredentialId,
103
+ rotatedAt: state.rotatedAt,
104
+ sessionId: state.sessionId,
105
+ lastSeenAt: state.lastSeenAt
106
+ };
107
+ }
99
108
  function rowToState(row) {
100
109
  const state = {
110
+ ...require_payload.credentialPayloadOf(row),
101
111
  userId: row.userId,
102
112
  issuedAt: row.issuedAt,
103
113
  expiresAt: row.expiresAt
104
114
  };
105
- if (row.claims !== void 0) state.claims = row.claims;
106
115
  if (row.metadata !== void 0) state.metadata = row.metadata;
107
116
  if (row.kind === "access" || row.kind === "refresh") state.kind = row.kind;
108
117
  if (row.parentCredentialId !== void 0) state.parentCredentialId = row.parentCredentialId;
109
118
  if (row.rotatedAt !== void 0) state.rotatedAt = row.rotatedAt;
119
+ if (row.sessionId !== void 0) state.sessionId = row.sessionId;
120
+ if (row.lastSeenAt !== void 0) state.lastSeenAt = row.lastSeenAt;
110
121
  return state;
111
122
  }
112
123
  //#endregion
@@ -1,20 +1,23 @@
1
- import { a as CredentialState, t as CredentialStore } from "./store-untAtWQz.cjs";
1
+ import { a as CredentialState, t as CredentialStore } from "./store-BG6m6oSJ.cjs";
2
2
 
3
3
  //#region src/atscript-db/index.d.ts
4
4
  /**
5
5
  * Persisted row shape — mirrors `AoothAuthCredential` from
6
- * `./auth-credential.as`. Re-declared here as a plain TS interface so
7
- * consumers can use the adapter without running the atscript build (and so
8
- * `@aooth/auth` doesn't need to depend on `@atscript/typescript` at build
9
- * time). When you DO wire the `.as` model, the shapes match by construction.
6
+ * `./auth-credential.as`. Re-declared here as a plain TS type so consumers can
7
+ * use the adapter without running the atscript build (and so `@aooth/auth`
8
+ * doesn't need to depend on `@atscript/typescript` at build time). When you DO
9
+ * wire the `.as` model, the shapes match by construction.
10
+ *
11
+ * The consumer's typed payload `TPayload` (the root fields they add to their
12
+ * `extends AoothAuthCredential` model) is intersected flat — those become real
13
+ * typed columns, replacing the dropped free-form `claims` blob.
10
14
  */
11
- interface AuthCredentialRow<TClaims extends object = object> {
15
+ type AuthCredentialRow<TPayload extends object = object> = {
12
16
  token: string;
13
17
  userId: string;
14
18
  issuedAt: number;
15
19
  expiresAt: number;
16
20
  kind?: string;
17
- claims?: TClaims;
18
21
  metadata?: {
19
22
  ip?: string;
20
23
  userAgent?: string;
@@ -23,25 +26,27 @@ interface AuthCredentialRow<TClaims extends object = object> {
23
26
  };
24
27
  parentCredentialId?: string;
25
28
  rotatedAt?: number;
26
- }
29
+ sessionId?: string;
30
+ lastSeenAt?: number;
31
+ } & TPayload;
27
32
  /**
28
33
  * Structural surface of `AtscriptDbTable` covering exactly the methods this
29
34
  * adapter calls. Kept loose to avoid pulling `@atscript/db` types into the
30
35
  * `@aooth/auth` public surface — consumers pass `db.getTable(AoothAuthCredential)`
31
36
  * directly and TypeScript matches by-shape.
32
37
  */
33
- interface AuthCredentialTable<TClaims extends object = object> {
34
- insertOne(row: AuthCredentialRow<TClaims>): Promise<{
38
+ interface AuthCredentialTable<TPayload extends object = object> {
39
+ insertOne(row: AuthCredentialRow<TPayload>): Promise<{
35
40
  insertedId: unknown;
36
41
  }>;
37
42
  findOne(query: {
38
43
  filter: Record<string, unknown>;
39
- }): Promise<AuthCredentialRow<TClaims> | null>;
44
+ }): Promise<AuthCredentialRow<TPayload> | null>;
40
45
  findMany(query: {
41
46
  filter?: Record<string, unknown>;
42
47
  controls?: Record<string, unknown>;
43
- }): Promise<AuthCredentialRow<TClaims>[]>;
44
- replaceOne(row: AuthCredentialRow<TClaims>): Promise<{
48
+ }): Promise<AuthCredentialRow<TPayload>[]>;
49
+ replaceOne(row: AuthCredentialRow<TPayload>): Promise<{
45
50
  matchedCount: number;
46
51
  modifiedCount: number;
47
52
  }>;
@@ -52,8 +57,8 @@ interface AuthCredentialTable<TClaims extends object = object> {
52
57
  deletedCount: number;
53
58
  }>;
54
59
  }
55
- interface CredentialStoreAtscriptDbOptions<TClaims extends object> {
56
- table: AuthCredentialTable<TClaims>;
60
+ interface CredentialStoreAtscriptDbOptions<TPayload extends object> {
61
+ table: AuthCredentialTable<TPayload>;
57
62
  }
58
63
  /**
59
64
  * atscript-db-backed `CredentialStore`.
@@ -68,16 +73,17 @@ interface CredentialStoreAtscriptDbOptions<TClaims extends object> {
68
73
  * `.as` model). Custom tables must keep `token` as PK or override the
69
74
  * adapter.
70
75
  */
71
- declare class CredentialStoreAtscriptDb<TClaims extends object = object> implements CredentialStore<TClaims> {
76
+ declare class CredentialStoreAtscriptDb<TPayload extends object = object> implements CredentialStore<TPayload> {
72
77
  private readonly table;
73
- constructor(opts: CredentialStoreAtscriptDbOptions<TClaims>);
74
- persist(state: CredentialState<TClaims>, ttl?: number): Promise<string>;
75
- retrieve(token: string): Promise<CredentialState<TClaims> | null>;
76
- consume(token: string): Promise<CredentialState<TClaims> | null>;
77
- update(token: string, state: CredentialState<TClaims>): Promise<string>;
78
+ constructor(opts: CredentialStoreAtscriptDbOptions<TPayload>);
79
+ persist(state: CredentialState & TPayload, ttl?: number): Promise<string>;
80
+ retrieve(token: string): Promise<(CredentialState & TPayload) | null>;
81
+ consume(token: string): Promise<(CredentialState & TPayload) | null>;
82
+ update(token: string, state: CredentialState & TPayload): Promise<string>;
78
83
  revoke(token: string): Promise<void>;
84
+ touch(token: string, at: number): Promise<void>;
79
85
  revokeAllForUser(userId: string): Promise<number>;
80
- listForUser(userId: string): Promise<Array<CredentialState<TClaims> & {
86
+ listForUser(userId: string): Promise<Array<CredentialState & TPayload & {
81
87
  token: string;
82
88
  }>>;
83
89
  }
@@ -1,20 +1,23 @@
1
- import { a as CredentialState, t as CredentialStore } from "./store-B1t8KkfA.mjs";
1
+ import { a as CredentialState, t as CredentialStore } from "./store-BG6m6oSJ.mjs";
2
2
 
3
3
  //#region src/atscript-db/index.d.ts
4
4
  /**
5
5
  * Persisted row shape — mirrors `AoothAuthCredential` from
6
- * `./auth-credential.as`. Re-declared here as a plain TS interface so
7
- * consumers can use the adapter without running the atscript build (and so
8
- * `@aooth/auth` doesn't need to depend on `@atscript/typescript` at build
9
- * time). When you DO wire the `.as` model, the shapes match by construction.
6
+ * `./auth-credential.as`. Re-declared here as a plain TS type so consumers can
7
+ * use the adapter without running the atscript build (and so `@aooth/auth`
8
+ * doesn't need to depend on `@atscript/typescript` at build time). When you DO
9
+ * wire the `.as` model, the shapes match by construction.
10
+ *
11
+ * The consumer's typed payload `TPayload` (the root fields they add to their
12
+ * `extends AoothAuthCredential` model) is intersected flat — those become real
13
+ * typed columns, replacing the dropped free-form `claims` blob.
10
14
  */
11
- interface AuthCredentialRow<TClaims extends object = object> {
15
+ type AuthCredentialRow<TPayload extends object = object> = {
12
16
  token: string;
13
17
  userId: string;
14
18
  issuedAt: number;
15
19
  expiresAt: number;
16
20
  kind?: string;
17
- claims?: TClaims;
18
21
  metadata?: {
19
22
  ip?: string;
20
23
  userAgent?: string;
@@ -23,25 +26,27 @@ interface AuthCredentialRow<TClaims extends object = object> {
23
26
  };
24
27
  parentCredentialId?: string;
25
28
  rotatedAt?: number;
26
- }
29
+ sessionId?: string;
30
+ lastSeenAt?: number;
31
+ } & TPayload;
27
32
  /**
28
33
  * Structural surface of `AtscriptDbTable` covering exactly the methods this
29
34
  * adapter calls. Kept loose to avoid pulling `@atscript/db` types into the
30
35
  * `@aooth/auth` public surface — consumers pass `db.getTable(AoothAuthCredential)`
31
36
  * directly and TypeScript matches by-shape.
32
37
  */
33
- interface AuthCredentialTable<TClaims extends object = object> {
34
- insertOne(row: AuthCredentialRow<TClaims>): Promise<{
38
+ interface AuthCredentialTable<TPayload extends object = object> {
39
+ insertOne(row: AuthCredentialRow<TPayload>): Promise<{
35
40
  insertedId: unknown;
36
41
  }>;
37
42
  findOne(query: {
38
43
  filter: Record<string, unknown>;
39
- }): Promise<AuthCredentialRow<TClaims> | null>;
44
+ }): Promise<AuthCredentialRow<TPayload> | null>;
40
45
  findMany(query: {
41
46
  filter?: Record<string, unknown>;
42
47
  controls?: Record<string, unknown>;
43
- }): Promise<AuthCredentialRow<TClaims>[]>;
44
- replaceOne(row: AuthCredentialRow<TClaims>): Promise<{
48
+ }): Promise<AuthCredentialRow<TPayload>[]>;
49
+ replaceOne(row: AuthCredentialRow<TPayload>): Promise<{
45
50
  matchedCount: number;
46
51
  modifiedCount: number;
47
52
  }>;
@@ -52,8 +57,8 @@ interface AuthCredentialTable<TClaims extends object = object> {
52
57
  deletedCount: number;
53
58
  }>;
54
59
  }
55
- interface CredentialStoreAtscriptDbOptions<TClaims extends object> {
56
- table: AuthCredentialTable<TClaims>;
60
+ interface CredentialStoreAtscriptDbOptions<TPayload extends object> {
61
+ table: AuthCredentialTable<TPayload>;
57
62
  }
58
63
  /**
59
64
  * atscript-db-backed `CredentialStore`.
@@ -68,16 +73,17 @@ interface CredentialStoreAtscriptDbOptions<TClaims extends object> {
68
73
  * `.as` model). Custom tables must keep `token` as PK or override the
69
74
  * adapter.
70
75
  */
71
- declare class CredentialStoreAtscriptDb<TClaims extends object = object> implements CredentialStore<TClaims> {
76
+ declare class CredentialStoreAtscriptDb<TPayload extends object = object> implements CredentialStore<TPayload> {
72
77
  private readonly table;
73
- constructor(opts: CredentialStoreAtscriptDbOptions<TClaims>);
74
- persist(state: CredentialState<TClaims>, ttl?: number): Promise<string>;
75
- retrieve(token: string): Promise<CredentialState<TClaims> | null>;
76
- consume(token: string): Promise<CredentialState<TClaims> | null>;
77
- update(token: string, state: CredentialState<TClaims>): Promise<string>;
78
+ constructor(opts: CredentialStoreAtscriptDbOptions<TPayload>);
79
+ persist(state: CredentialState & TPayload, ttl?: number): Promise<string>;
80
+ retrieve(token: string): Promise<(CredentialState & TPayload) | null>;
81
+ consume(token: string): Promise<(CredentialState & TPayload) | null>;
82
+ update(token: string, state: CredentialState & TPayload): Promise<string>;
78
83
  revoke(token: string): Promise<void>;
84
+ touch(token: string, at: number): Promise<void>;
79
85
  revokeAllForUser(userId: string): Promise<number>;
80
- listForUser(userId: string): Promise<Array<CredentialState<TClaims> & {
86
+ listForUser(userId: string): Promise<Array<CredentialState & TPayload & {
81
87
  token: string;
82
88
  }>>;
83
89
  }
@@ -1,3 +1,4 @@
1
+ import { t as credentialPayloadOf } from "./payload-D-DzH5-J.mjs";
1
2
  import { randomUUID } from "node:crypto";
2
3
  //#region src/atscript-db/index.ts
3
4
  /**
@@ -21,18 +22,7 @@ var CredentialStoreAtscriptDb = class {
21
22
  async persist(state, ttl) {
22
23
  const token = randomUUID();
23
24
  const expiresAt = typeof ttl === "number" ? Date.now() + ttl : state.expiresAt;
24
- const row = {
25
- token,
26
- userId: state.userId,
27
- issuedAt: state.issuedAt,
28
- expiresAt,
29
- kind: state.kind,
30
- claims: state.claims,
31
- metadata: state.metadata,
32
- parentCredentialId: state.parentCredentialId,
33
- rotatedAt: state.rotatedAt
34
- };
35
- await this.table.insertOne(row);
25
+ await this.table.insertOne(stateToRow(state, token, expiresAt));
36
26
  return token;
37
27
  }
38
28
  async retrieve(token) {
@@ -56,23 +46,21 @@ var CredentialStoreAtscriptDb = class {
56
46
  await this.revoke(token);
57
47
  return token;
58
48
  }
59
- const row = {
60
- token,
61
- userId: state.userId,
62
- issuedAt: state.issuedAt,
63
- expiresAt: state.expiresAt,
64
- kind: state.kind,
65
- claims: state.claims,
66
- metadata: state.metadata,
67
- parentCredentialId: state.parentCredentialId,
68
- rotatedAt: state.rotatedAt
69
- };
70
- await this.table.replaceOne(row);
49
+ await this.table.replaceOne(stateToRow(state, token, state.expiresAt));
71
50
  return token;
72
51
  }
73
52
  async revoke(token) {
74
53
  await this.table.deleteOne(token);
75
54
  }
55
+ async touch(token, at) {
56
+ const row = await this.table.findOne({ filter: { token } });
57
+ if (!row) return;
58
+ if (row.expiresAt <= Date.now()) return;
59
+ await this.table.replaceOne({
60
+ ...row,
61
+ lastSeenAt: at
62
+ });
63
+ }
76
64
  async revokeAllForUser(userId) {
77
65
  return (await this.table.deleteMany({ userId })).deletedCount;
78
66
  }
@@ -95,17 +83,40 @@ var CredentialStoreAtscriptDb = class {
95
83
  return out;
96
84
  }
97
85
  };
86
+ /**
87
+ * Build the persisted row from a credential state: typed payload columns first
88
+ * (so an envelope field wins a name clash), then the fixed envelope fields and
89
+ * the resolved `token` + `expiresAt`. Shared by `persist` and `update`, which
90
+ * differ only in the `expiresAt` they resolve.
91
+ */
92
+ function stateToRow(state, token, expiresAt) {
93
+ return {
94
+ ...credentialPayloadOf(state),
95
+ token,
96
+ userId: state.userId,
97
+ issuedAt: state.issuedAt,
98
+ expiresAt,
99
+ kind: state.kind,
100
+ metadata: state.metadata,
101
+ parentCredentialId: state.parentCredentialId,
102
+ rotatedAt: state.rotatedAt,
103
+ sessionId: state.sessionId,
104
+ lastSeenAt: state.lastSeenAt
105
+ };
106
+ }
98
107
  function rowToState(row) {
99
108
  const state = {
109
+ ...credentialPayloadOf(row),
100
110
  userId: row.userId,
101
111
  issuedAt: row.issuedAt,
102
112
  expiresAt: row.expiresAt
103
113
  };
104
- if (row.claims !== void 0) state.claims = row.claims;
105
114
  if (row.metadata !== void 0) state.metadata = row.metadata;
106
115
  if (row.kind === "access" || row.kind === "refresh") state.kind = row.kind;
107
116
  if (row.parentCredentialId !== void 0) state.parentCredentialId = row.parentCredentialId;
108
117
  if (row.rotatedAt !== void 0) state.rotatedAt = row.rotatedAt;
118
+ if (row.sessionId !== void 0) state.sessionId = row.sessionId;
119
+ if (row.lastSeenAt !== void 0) state.lastSeenAt = row.lastSeenAt;
109
120
  return state;
110
121
  }
111
122
  //#endregion