@gauts/auth 0.8.2 → 0.10.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.
- package/README.md +376 -140
- package/SECURITY.md +8 -4
- package/dist/adapters/drizzle/config.d.ts +11 -0
- package/dist/adapters/drizzle/config.d.ts.map +1 -0
- package/dist/adapters/drizzle/config.js +147 -0
- package/dist/adapters/drizzle/config.js.map +1 -0
- package/dist/adapters/drizzle/index.d.ts +4 -0
- package/dist/adapters/drizzle/index.d.ts.map +1 -0
- package/dist/adapters/drizzle/index.js +156 -0
- package/dist/adapters/drizzle/index.js.map +1 -0
- package/dist/adapters/drizzle/model.d.ts +21 -0
- package/dist/adapters/drizzle/model.d.ts.map +1 -0
- package/dist/adapters/drizzle/model.js +61 -0
- package/dist/adapters/drizzle/model.js.map +1 -0
- package/dist/adapters/drizzle/schema.d.ts +311 -0
- package/dist/adapters/drizzle/schema.d.ts.map +1 -0
- package/dist/adapters/drizzle/schema.js +37 -0
- package/dist/adapters/drizzle/schema.js.map +1 -0
- package/dist/adapters/drizzle/types.d.ts +109 -0
- package/dist/adapters/drizzle/types.d.ts.map +1 -0
- package/dist/adapters/drizzle/types.js +2 -0
- package/dist/adapters/drizzle/types.js.map +1 -0
- package/dist/adapters/express/index.d.ts +77 -0
- package/dist/adapters/express/index.d.ts.map +1 -0
- package/dist/adapters/express/index.js +72 -0
- package/dist/adapters/express/index.js.map +1 -0
- package/dist/adapters/express/social.d.ts +29 -0
- package/dist/adapters/express/social.d.ts.map +1 -0
- package/dist/adapters/express/social.js +44 -0
- package/dist/adapters/express/social.js.map +1 -0
- package/dist/adapters/fastify/index.d.ts +79 -0
- package/dist/adapters/fastify/index.d.ts.map +1 -0
- package/dist/adapters/fastify/index.js +100 -0
- package/dist/adapters/fastify/index.js.map +1 -0
- package/dist/adapters/fastify/social.d.ts +27 -0
- package/dist/adapters/fastify/social.d.ts.map +1 -0
- package/dist/adapters/fastify/social.js +48 -0
- package/dist/adapters/fastify/social.js.map +1 -0
- package/dist/adapters/hono/index.d.ts +10 -23
- package/dist/adapters/hono/index.d.ts.map +1 -1
- package/dist/adapters/hono/index.js +32 -224
- package/dist/adapters/hono/index.js.map +1 -1
- package/dist/adapters/hono/social.d.ts +4 -10
- package/dist/adapters/hono/social.d.ts.map +1 -1
- package/dist/adapters/hono/social.js +25 -221
- package/dist/adapters/hono/social.js.map +1 -1
- package/dist/adapters/model.d.ts +33 -0
- package/dist/adapters/model.d.ts.map +1 -0
- package/dist/adapters/model.js +87 -0
- package/dist/adapters/model.js.map +1 -0
- package/dist/adapters/next/index.d.ts +1 -1
- package/dist/adapters/next/index.d.ts.map +1 -1
- package/dist/adapters/next/index.js +7 -3
- package/dist/adapters/next/index.js.map +1 -1
- package/dist/adapters/prisma/config.d.ts.map +1 -1
- package/dist/adapters/prisma/config.js +1 -4
- package/dist/adapters/prisma/config.js.map +1 -1
- package/dist/adapters/prisma/model.d.ts +7 -8
- package/dist/adapters/prisma/model.d.ts.map +1 -1
- package/dist/adapters/prisma/model.js +11 -79
- package/dist/adapters/prisma/model.js.map +1 -1
- package/dist/adapters/utils/cookie.d.ts +17 -0
- package/dist/adapters/utils/cookie.d.ts.map +1 -0
- package/dist/adapters/utils/cookie.js +59 -0
- package/dist/adapters/utils/cookie.js.map +1 -0
- package/dist/adapters/utils/session.d.ts +4 -0
- package/dist/adapters/utils/session.d.ts.map +1 -0
- package/dist/adapters/utils/session.js +208 -0
- package/dist/adapters/utils/session.js.map +1 -0
- package/dist/adapters/utils/social.d.ts +51 -0
- package/dist/adapters/utils/social.d.ts.map +1 -0
- package/dist/adapters/utils/social.js +278 -0
- package/dist/adapters/utils/social.js.map +1 -0
- package/dist/adapters/utils/types.d.ts +61 -0
- package/dist/adapters/utils/types.d.ts.map +1 -0
- package/dist/adapters/utils/types.js +2 -0
- package/dist/adapters/utils/types.js.map +1 -0
- package/dist/config.d.ts +1 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -2
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/session/cookie.d.ts +6 -8
- package/dist/session/cookie.d.ts.map +1 -1
- package/dist/session/cookie.js +7 -24
- package/dist/session/cookie.js.map +1 -1
- package/dist/session/state.d.ts +41 -0
- package/dist/session/state.d.ts.map +1 -0
- package/dist/session/state.js +192 -0
- package/dist/session/state.js.map +1 -0
- package/package.json +40 -3
- package/src/adapters/drizzle/schema.ts +47 -0
- package/src/adapters/prisma/schema.prisma +38 -0
- package/dist/session/cache.d.ts +0 -32
- package/dist/session/cache.d.ts.map +0 -1
- package/dist/session/cache.js +0 -138
- package/dist/session/cache.js.map +0 -1
package/SECURITY.md
CHANGED
|
@@ -29,20 +29,24 @@ Security reports may cover the password service, session core, database adapters
|
|
|
29
29
|
|
|
30
30
|
Application-specific authorization, rate limiting, CSRF, CORS, proxy trust, deployment, and database access policies remain the consuming application's responsibility unless the vulnerability is caused by package behavior.
|
|
31
31
|
|
|
32
|
-
## Signed session
|
|
32
|
+
## Signed session context
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Browser integration uses an opaque session-token cookie and a signed context cookie. The context is signed with HMAC-SHA-256 using an API-only application secret of at least 32 bytes and is cryptographically bound to the opaque token. It contains session expiry and renewal scheduling plus optional short cached account/session data. It never authenticates without the opaque token.
|
|
35
35
|
|
|
36
|
-
The
|
|
36
|
+
The API verifies the context signature before trusting any cached value. Missing, malformed, expired, altered, or incorrectly bound context data causes normal database validation and a new context cookie. It does not revoke an otherwise valid opaque session. The Next.js adapter may decode the expiry and renewal values without the secret, but treats them only as untrusted scheduling hints.
|
|
37
|
+
|
|
38
|
+
The optional browser cache is disabled when omitted. When configured, it is accepted only for `GET` and `HEAD` requests and remains bound to its own expiry, the authoritative session expiry, and the configured client fields.
|
|
37
39
|
|
|
38
40
|
Cookie caching introduces a bounded consistency window. A session revoked on another device, or selected account or relation access changed in the database, may remain readable until the cache TTL expires. Unsafe methods, renewal, logout, WebSockets, and direct core calls always validate through the database. Applications requiring immediate cross-device read revocation must leave the cache disabled or provide shared server-side enforcement outside this package.
|
|
39
41
|
|
|
40
|
-
Keep `AUTH_SECRET` in the API environment. Do not expose it to browser code or share it with a frontend merely to inspect
|
|
42
|
+
Keep `AUTH_SECRET` in the API environment. Do not expose it to browser code or share it with a frontend merely to inspect scheduling values. Those values are intentionally untrusted and never authenticate or renew a session by themselves.
|
|
41
43
|
|
|
42
44
|
## Session lifetime
|
|
43
45
|
|
|
44
46
|
Sliding renewal is limited by `session.maxLifetime`, which defaults to 30 days from the original login. The maximum expiry is derived from the immutable session `created_at` value and enforced by the core during resolution and renewal. Browser cookies and cached session data never outlive the authoritative session expiry.
|
|
45
47
|
|
|
48
|
+
Framework middleware renews inline when the verified context says renewal is due. The explicit renewal endpoint performs the same database-backed operation for server-rendered navigation. Both paths retain the same opaque token and rewrite the session and context cookie expiries.
|
|
49
|
+
|
|
46
50
|
Activity and possession of the session token cannot extend this absolute limit. After it is reached, the user must authenticate again and receive a new session token.
|
|
47
51
|
|
|
48
52
|
## Social authentication
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
2
|
+
import type { ResolvedDrizzleModels } from "./types.js";
|
|
3
|
+
export declare const DRIZZLE_FIELDS: {
|
|
4
|
+
readonly accounts: readonly ["id", "email", "user_id"];
|
|
5
|
+
readonly sessions: readonly ["account_id", "agent", "country", "created_at", "expires_at", "id", "ip", "platform", "revoked_at", "token_hash", "updated_at"];
|
|
6
|
+
readonly socials: readonly ["account_id", "created_at", "id", "provider", "provider_id"];
|
|
7
|
+
readonly users: readonly ["id", "name"];
|
|
8
|
+
};
|
|
9
|
+
export declare const resolveDrizzleModels: (input: unknown) => ResolvedDrizzleModels;
|
|
10
|
+
export declare const getDrizzleSource: (table: AnyMySqlTable) => string;
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/adapters/drizzle/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAK5D,OAAO,KAAK,EAA4B,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAkClF,eAAO,MAAM,cAAc;;;;;CAiBjB,CAAC;AA+HX,eAAO,MAAM,oBAAoB,GAAI,OAAO,OAAO,KAAG,qBAmCrD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,OAAO,aAAa,KAAG,MAEvD,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { getTableColumns, getTableName, isTable } from "drizzle-orm";
|
|
2
|
+
import { createError } from "../../errors.js";
|
|
3
|
+
import { isRecord } from "../../session/guards.js";
|
|
4
|
+
import { isPrivateField } from "../model.js";
|
|
5
|
+
export const DRIZZLE_FIELDS = {
|
|
6
|
+
accounts: ["id", "email", "user_id"],
|
|
7
|
+
sessions: [
|
|
8
|
+
"account_id",
|
|
9
|
+
"agent",
|
|
10
|
+
"country",
|
|
11
|
+
"created_at",
|
|
12
|
+
"expires_at",
|
|
13
|
+
"id",
|
|
14
|
+
"ip",
|
|
15
|
+
"platform",
|
|
16
|
+
"revoked_at",
|
|
17
|
+
"token_hash",
|
|
18
|
+
"updated_at",
|
|
19
|
+
],
|
|
20
|
+
socials: ["account_id", "created_at", "id", "provider", "provider_id"],
|
|
21
|
+
users: ["id", "name"],
|
|
22
|
+
};
|
|
23
|
+
const DRIZZLE_SELECT = {
|
|
24
|
+
accounts: ["id", "email"],
|
|
25
|
+
users: ["id", "name"],
|
|
26
|
+
};
|
|
27
|
+
const isAuthScalar = (value) => {
|
|
28
|
+
return (value === null ||
|
|
29
|
+
typeof value === "boolean" ||
|
|
30
|
+
typeof value === "string" ||
|
|
31
|
+
(typeof value === "number" && Number.isFinite(value)));
|
|
32
|
+
};
|
|
33
|
+
const isAccessValue = (value) => {
|
|
34
|
+
return Array.isArray(value)
|
|
35
|
+
? value.length > 0 && value.every(isAuthScalar)
|
|
36
|
+
: isAuthScalar(value);
|
|
37
|
+
};
|
|
38
|
+
const requireTable = ({ fields, input, path }) => {
|
|
39
|
+
if (!isTable(input)) {
|
|
40
|
+
throw createError({
|
|
41
|
+
code: "AUTH_CONFIG_INVALID",
|
|
42
|
+
message: `${path}.table must be a Drizzle MySQL table.`,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const columns = getTableColumns(input);
|
|
46
|
+
const missing = fields.filter((field) => !(field in columns));
|
|
47
|
+
if (missing.length > 0) {
|
|
48
|
+
throw createError({
|
|
49
|
+
code: "AUTH_CONFIG_INVALID",
|
|
50
|
+
message: `${path}.table is missing required columns: ${missing.join(", ")}.`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return input;
|
|
54
|
+
};
|
|
55
|
+
const resolveSelect = ({ columns, defaults, input, path, }) => {
|
|
56
|
+
if (input === undefined) {
|
|
57
|
+
return defaults;
|
|
58
|
+
}
|
|
59
|
+
if (!Array.isArray(input) ||
|
|
60
|
+
input.some((field) => typeof field !== "string" || !field.trim()) ||
|
|
61
|
+
new Set(input).size !== input.length ||
|
|
62
|
+
input.some((field) => typeof field === "string" && isPrivateField(field)) ||
|
|
63
|
+
input.some((field) => typeof field === "string" && !(field in columns))) {
|
|
64
|
+
throw createError({
|
|
65
|
+
code: "AUTH_CONFIG_INVALID",
|
|
66
|
+
message: `${path}.select must contain unique public scalar column names.`,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return [...new Set([...defaults, ...input])];
|
|
70
|
+
};
|
|
71
|
+
const resolveAccess = ({ columns, input, path, }) => {
|
|
72
|
+
if (input === undefined) {
|
|
73
|
+
return {};
|
|
74
|
+
}
|
|
75
|
+
if (!isRecord(input) ||
|
|
76
|
+
Object.keys(input).some(isPrivateField) ||
|
|
77
|
+
Object.keys(input).some((field) => !(field in columns)) ||
|
|
78
|
+
Object.values(input).some((value) => !isAccessValue(value))) {
|
|
79
|
+
throw createError({
|
|
80
|
+
code: "AUTH_CONFIG_INVALID",
|
|
81
|
+
message: `${path}.access contains an invalid condition.`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return input;
|
|
85
|
+
};
|
|
86
|
+
const resolveDataModel = ({ defaults, fields, input, path, }) => {
|
|
87
|
+
if (!isRecord(input)) {
|
|
88
|
+
throw createError({
|
|
89
|
+
code: "AUTH_CONFIG_INVALID",
|
|
90
|
+
message: `${path} model configuration is invalid.`,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const table = requireTable({ fields, input: input.table, path });
|
|
94
|
+
const columns = getTableColumns(table);
|
|
95
|
+
return {
|
|
96
|
+
access: resolveAccess({ columns, input: input.access, path }),
|
|
97
|
+
select: resolveSelect({ columns, defaults, input: input.select, path }),
|
|
98
|
+
table,
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
const resolveTableModel = ({ fields, input, path }) => {
|
|
102
|
+
if (!isRecord(input)) {
|
|
103
|
+
throw createError({
|
|
104
|
+
code: "AUTH_CONFIG_INVALID",
|
|
105
|
+
message: `${path} model configuration is invalid.`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return requireTable({ fields, input: input.table, path });
|
|
109
|
+
};
|
|
110
|
+
export const resolveDrizzleModels = (input) => {
|
|
111
|
+
if (!isRecord(input)) {
|
|
112
|
+
throw createError({
|
|
113
|
+
code: "AUTH_CONFIG_INVALID",
|
|
114
|
+
message: "Drizzle models configuration is invalid.",
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
accounts: resolveDataModel({
|
|
119
|
+
defaults: DRIZZLE_SELECT.accounts,
|
|
120
|
+
fields: DRIZZLE_FIELDS.accounts,
|
|
121
|
+
input: input.accounts,
|
|
122
|
+
path: "models.accounts",
|
|
123
|
+
}),
|
|
124
|
+
sessions: resolveTableModel({
|
|
125
|
+
fields: DRIZZLE_FIELDS.sessions,
|
|
126
|
+
input: input.sessions,
|
|
127
|
+
path: "models.sessions",
|
|
128
|
+
}),
|
|
129
|
+
socials: input.socials === undefined
|
|
130
|
+
? null
|
|
131
|
+
: resolveTableModel({
|
|
132
|
+
fields: DRIZZLE_FIELDS.socials,
|
|
133
|
+
input: input.socials,
|
|
134
|
+
path: "models.socials",
|
|
135
|
+
}),
|
|
136
|
+
users: resolveDataModel({
|
|
137
|
+
defaults: DRIZZLE_SELECT.users,
|
|
138
|
+
fields: DRIZZLE_FIELDS.users,
|
|
139
|
+
input: input.users,
|
|
140
|
+
path: "models.users",
|
|
141
|
+
}),
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
export const getDrizzleSource = (table) => {
|
|
145
|
+
return getTableName(table);
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/adapters/drizzle/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CreateDrizzleAdapter } from "./types.js";
|
|
2
|
+
export type { DrizzleAccount, DrizzleAdapterInput, DrizzleDataModelConfig, DrizzleModelsConfig, DrizzleTableModelConfig, DrizzleUser, } from "./types.js";
|
|
3
|
+
export declare const createDrizzleAdapter: CreateDrizzleAdapter;
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/drizzle/index.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACR,oBAAoB,EAMvB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACR,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,WAAW,GACd,MAAM,YAAY,CAAC;AAkCpB,eAAO,MAAM,oBAAoB,EAAE,oBAoLlC,CAAC"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { and, desc, eq, getTableColumns, gt, inArray, isNull } from "drizzle-orm";
|
|
3
|
+
import { createError } from "../../errors.js";
|
|
4
|
+
import { isRecord } from "../../session/guards.js";
|
|
5
|
+
import { DRIZZLE_FIELDS, resolveDrizzleModels } from "./config.js";
|
|
6
|
+
import { createModelSelect, createSessionSelect, readAccount, requireAuthRow, requireRow, requireRows, } from "./model.js";
|
|
7
|
+
const requireClient = (value) => {
|
|
8
|
+
if (!isRecord(value) ||
|
|
9
|
+
typeof value.insert !== "function" ||
|
|
10
|
+
typeof value.select !== "function" ||
|
|
11
|
+
typeof value.transaction !== "function" ||
|
|
12
|
+
typeof value.update !== "function") {
|
|
13
|
+
throw createError({
|
|
14
|
+
code: "AUTH_CONFIG_INVALID",
|
|
15
|
+
message: "Drizzle MySQL client is invalid.",
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
};
|
|
20
|
+
const getColumns = ({ fields, table, }) => {
|
|
21
|
+
const columns = getTableColumns(table);
|
|
22
|
+
return Object.fromEntries(fields.map((field) => [field, columns[field]]));
|
|
23
|
+
};
|
|
24
|
+
export const createDrizzleAdapter = (input) => {
|
|
25
|
+
const client = requireClient(input.client);
|
|
26
|
+
const models = resolveDrizzleModels(input.models);
|
|
27
|
+
const accountColumns = getColumns({
|
|
28
|
+
fields: DRIZZLE_FIELDS.accounts,
|
|
29
|
+
table: models.accounts.table,
|
|
30
|
+
});
|
|
31
|
+
const sessionColumns = getColumns({
|
|
32
|
+
fields: DRIZZLE_FIELDS.sessions,
|
|
33
|
+
table: models.sessions,
|
|
34
|
+
});
|
|
35
|
+
const userColumns = getColumns({
|
|
36
|
+
fields: DRIZZLE_FIELDS.users,
|
|
37
|
+
table: models.users.table,
|
|
38
|
+
});
|
|
39
|
+
const accountSelect = createModelSelect({ model: models.accounts });
|
|
40
|
+
const sessionSelect = createSessionSelect(models);
|
|
41
|
+
const userSelect = createModelSelect({ model: models.users });
|
|
42
|
+
const readSocialAccount = (value) => {
|
|
43
|
+
const resolved = readAccount({ models, value });
|
|
44
|
+
return {
|
|
45
|
+
account: resolved.account,
|
|
46
|
+
allowed: resolved.allowed,
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const findAccount = async (where) => {
|
|
50
|
+
const rows = await client
|
|
51
|
+
.select({ account: accountSelect, user: userSelect })
|
|
52
|
+
.from(models.accounts.table)
|
|
53
|
+
.innerJoin(models.users.table, eq(accountColumns.user_id, userColumns.id))
|
|
54
|
+
.where(where)
|
|
55
|
+
.limit(1);
|
|
56
|
+
return rows[0] === undefined ? null : readSocialAccount(rows[0]);
|
|
57
|
+
};
|
|
58
|
+
const db = {
|
|
59
|
+
create: async (session) => {
|
|
60
|
+
await client.insert(models.sessions).values(session);
|
|
61
|
+
},
|
|
62
|
+
find: async ({ account_id, session_id }) => {
|
|
63
|
+
const rows = await client
|
|
64
|
+
.select(sessionSelect)
|
|
65
|
+
.from(models.sessions)
|
|
66
|
+
.where(and(eq(sessionColumns.account_id, account_id), eq(sessionColumns.id, session_id)))
|
|
67
|
+
.limit(1);
|
|
68
|
+
return rows[0] === undefined ? null : requireRow(rows[0]);
|
|
69
|
+
},
|
|
70
|
+
findActive: async ({ account_id, now }) => {
|
|
71
|
+
const rows = await client
|
|
72
|
+
.select(sessionSelect)
|
|
73
|
+
.from(models.sessions)
|
|
74
|
+
.where(and(eq(sessionColumns.account_id, account_id), gt(sessionColumns.expires_at, now), isNull(sessionColumns.revoked_at)))
|
|
75
|
+
.orderBy(desc(sessionColumns.created_at));
|
|
76
|
+
return requireRows(rows);
|
|
77
|
+
},
|
|
78
|
+
findToken: async (token_hash) => {
|
|
79
|
+
const rows = await client
|
|
80
|
+
.select({
|
|
81
|
+
account: accountSelect,
|
|
82
|
+
session: sessionSelect,
|
|
83
|
+
user: userSelect,
|
|
84
|
+
})
|
|
85
|
+
.from(models.sessions)
|
|
86
|
+
.innerJoin(models.accounts.table, eq(sessionColumns.account_id, accountColumns.id))
|
|
87
|
+
.innerJoin(models.users.table, eq(accountColumns.user_id, userColumns.id))
|
|
88
|
+
.where(eq(sessionColumns.token_hash, token_hash))
|
|
89
|
+
.limit(1);
|
|
90
|
+
return rows[0] === undefined
|
|
91
|
+
? null
|
|
92
|
+
: requireAuthRow({ models, value: rows[0] });
|
|
93
|
+
},
|
|
94
|
+
revoke: async ({ revoked_at, session_ids }) => {
|
|
95
|
+
if (session_ids.length === 0) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
await client
|
|
99
|
+
.update(models.sessions)
|
|
100
|
+
.set({
|
|
101
|
+
revoked_at,
|
|
102
|
+
updated_at: revoked_at,
|
|
103
|
+
})
|
|
104
|
+
.where(and(inArray(sessionColumns.id, session_ids), isNull(sessionColumns.revoked_at)));
|
|
105
|
+
},
|
|
106
|
+
updateExpiry: async ({ expires_at, session_id, updated_at }) => {
|
|
107
|
+
await client
|
|
108
|
+
.update(models.sessions)
|
|
109
|
+
.set({ expires_at, updated_at })
|
|
110
|
+
.where(eq(sessionColumns.id, session_id));
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
const socialTable = models.socials;
|
|
114
|
+
if (socialTable === null) {
|
|
115
|
+
return db;
|
|
116
|
+
}
|
|
117
|
+
const socialColumns = getColumns({
|
|
118
|
+
fields: DRIZZLE_FIELDS.socials,
|
|
119
|
+
table: socialTable,
|
|
120
|
+
});
|
|
121
|
+
const social = {
|
|
122
|
+
createAccount: async ({ email, name }) => {
|
|
123
|
+
return client.transaction(async (transaction) => {
|
|
124
|
+
const accountId = randomUUID();
|
|
125
|
+
const userId = randomUUID();
|
|
126
|
+
await transaction.insert(models.users.table).values({
|
|
127
|
+
id: userId,
|
|
128
|
+
name,
|
|
129
|
+
});
|
|
130
|
+
await transaction.insert(models.accounts.table).values({
|
|
131
|
+
email,
|
|
132
|
+
id: accountId,
|
|
133
|
+
user_id: userId,
|
|
134
|
+
});
|
|
135
|
+
return accountId;
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
createSocial: async (socialRecord) => {
|
|
139
|
+
await client.insert(socialTable).values(socialRecord);
|
|
140
|
+
},
|
|
141
|
+
findAccount: async (account_id) => findAccount(eq(accountColumns.id, account_id)),
|
|
142
|
+
findEmail: async (email) => findAccount(eq(accountColumns.email, email)),
|
|
143
|
+
findSocial: async ({ provider, provider_id }) => {
|
|
144
|
+
const rows = await client
|
|
145
|
+
.select({ account: accountSelect, user: userSelect })
|
|
146
|
+
.from(socialTable)
|
|
147
|
+
.innerJoin(models.accounts.table, eq(socialColumns.account_id, accountColumns.id))
|
|
148
|
+
.innerJoin(models.users.table, eq(accountColumns.user_id, userColumns.id))
|
|
149
|
+
.where(and(eq(socialColumns.provider, provider), eq(socialColumns.provider_id, provider_id)))
|
|
150
|
+
.limit(1);
|
|
151
|
+
return rows[0] === undefined ? null : readSocialAccount(rows[0]);
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
return { ...db, ...social };
|
|
155
|
+
};
|
|
156
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/drizzle/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SelectedFieldsFlat } from "drizzle-orm/mysql-core";
|
|
2
|
+
import type { AuthSessionRecord, SessionRecord } from "../../session/types.js";
|
|
3
|
+
import type { ResolvedDrizzleDataModel, ResolvedDrizzleModels } from "./types.js";
|
|
4
|
+
type ReadAccountInput = {
|
|
5
|
+
models: ResolvedDrizzleModels;
|
|
6
|
+
value: unknown;
|
|
7
|
+
};
|
|
8
|
+
type CreateModelSelectInput = {
|
|
9
|
+
model: ResolvedDrizzleDataModel;
|
|
10
|
+
};
|
|
11
|
+
export declare const createModelSelect: ({ model }: CreateModelSelectInput) => SelectedFieldsFlat;
|
|
12
|
+
export declare const createSessionSelect: (models: ResolvedDrizzleModels) => SelectedFieldsFlat;
|
|
13
|
+
export declare const readAccount: ({ models, value }: ReadAccountInput) => {
|
|
14
|
+
account: import("../../session/types.js").AuthAccount;
|
|
15
|
+
allowed: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare const requireRow: (value: unknown) => SessionRecord;
|
|
18
|
+
export declare const requireRows: (value: unknown) => SessionRecord[];
|
|
19
|
+
export declare const requireAuthRow: ({ models, value }: ReadAccountInput) => AuthSessionRecord;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/adapters/drizzle/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAElF,KAAK,gBAAgB,GAAG;IACpB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,KAAK,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC1B,KAAK,EAAE,wBAAwB,CAAC;CACnC,CAAC;AAaF,eAAO,MAAM,iBAAiB,GAAI,WAAW,sBAAsB,KAAG,kBAKrE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,QAAQ,qBAAqB,KAAG,kBASnE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,mBAAmB,gBAAgB;;;CAkB9D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,aAE3C,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,KAAG,aAAa,EAEzD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,mBAAmB,gBAAgB,KAAG,iBAapE,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { getTableColumns } from "drizzle-orm";
|
|
2
|
+
import { isRecord } from "../../session/guards.js";
|
|
3
|
+
import { readAdapterAccount, requireSessionRecord, requireSessionRecords } from "../model.js";
|
|
4
|
+
import { DRIZZLE_FIELDS, getDrizzleSource } from "./config.js";
|
|
5
|
+
const pickColumns = ({ fields, model }) => {
|
|
6
|
+
const columns = getTableColumns(model.table);
|
|
7
|
+
return Object.fromEntries(fields.map((field) => [field, columns[field]]));
|
|
8
|
+
};
|
|
9
|
+
export const createModelSelect = ({ model }) => {
|
|
10
|
+
return pickColumns({
|
|
11
|
+
fields: [...new Set([...model.select, ...Object.keys(model.access)])],
|
|
12
|
+
model,
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
export const createSessionSelect = (models) => {
|
|
16
|
+
return pickColumns({
|
|
17
|
+
fields: DRIZZLE_FIELDS.sessions.filter((field) => field !== "country"),
|
|
18
|
+
model: {
|
|
19
|
+
access: {},
|
|
20
|
+
select: [],
|
|
21
|
+
table: models.sessions,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
export const readAccount = ({ models, value }) => {
|
|
26
|
+
if (!isRecord(value)) {
|
|
27
|
+
throw new Error("Drizzle account relation returned invalid data.");
|
|
28
|
+
}
|
|
29
|
+
return readAdapterAccount({
|
|
30
|
+
account: value.account,
|
|
31
|
+
accounts: {
|
|
32
|
+
...models.accounts,
|
|
33
|
+
source: getDrizzleSource(models.accounts.table),
|
|
34
|
+
},
|
|
35
|
+
adapter: "Drizzle",
|
|
36
|
+
user: value.user,
|
|
37
|
+
users: {
|
|
38
|
+
...models.users,
|
|
39
|
+
source: getDrizzleSource(models.users.table),
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
export const requireRow = (value) => {
|
|
44
|
+
return requireSessionRecord({ adapter: "Drizzle", value });
|
|
45
|
+
};
|
|
46
|
+
export const requireRows = (value) => {
|
|
47
|
+
return requireSessionRecords({ adapter: "Drizzle", value });
|
|
48
|
+
};
|
|
49
|
+
export const requireAuthRow = ({ models, value }) => {
|
|
50
|
+
if (!isRecord(value)) {
|
|
51
|
+
throw new Error("Drizzle session table returned invalid data.");
|
|
52
|
+
}
|
|
53
|
+
const session = requireRow(value.session);
|
|
54
|
+
const resolved = readAccount({ models, value });
|
|
55
|
+
return {
|
|
56
|
+
...session,
|
|
57
|
+
account: resolved.account,
|
|
58
|
+
allowed: resolved.allowed,
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/adapters/drizzle/model.ts"],"names":[],"mappings":"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"}
|