@batijs/cli 0.0.443 → 0.0.445

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.
Files changed (125) hide show
  1. package/dist/boilerplates/@batijs/auth0/files/$.env.js +5 -5
  2. package/dist/boilerplates/@batijs/auth0/files/$README.md.js +3 -3
  3. package/dist/boilerplates/@batijs/authjs/files/$package.json.js +5 -5
  4. package/dist/boilerplates/@batijs/aws/files/$README.md.js +3 -3
  5. package/dist/boilerplates/@batijs/aws/files/$package.json.js +9 -9
  6. package/dist/boilerplates/@batijs/aws/files/$tsconfig.json.js +3 -3
  7. package/dist/boilerplates/@batijs/biome/files/$package.json.js +4 -4
  8. package/dist/boilerplates/@batijs/cloudflare/files/$package.json.js +6 -6
  9. package/dist/boilerplates/@batijs/cloudflare/files/$tsconfig.json.js +3 -3
  10. package/dist/boilerplates/@batijs/cloudflare/files/$vite.config.ts.js +5 -5
  11. package/dist/boilerplates/@batijs/compiled/files/$package.json.js +5 -5
  12. package/dist/boilerplates/@batijs/compiled/files/$vite.config.ts.js +5 -5
  13. package/dist/boilerplates/@batijs/d1/files/$README.md.js +3 -3
  14. package/dist/boilerplates/@batijs/d1/files/$package.json.js +7 -7
  15. package/dist/boilerplates/@batijs/d1/files/$tsconfig.json.js +3 -3
  16. package/dist/boilerplates/@batijs/d1/files/$wrangler.toml.js +1 -1
  17. package/dist/boilerplates/@batijs/d1-sqlite/files/$package.json.js +6 -12
  18. package/dist/boilerplates/@batijs/drizzle/files/$.env.js +3 -3
  19. package/dist/boilerplates/@batijs/drizzle/files/$README.md.js +3 -3
  20. package/dist/boilerplates/@batijs/drizzle/files/$package.json.js +4 -16
  21. package/dist/boilerplates/@batijs/eslint/files/$package.json.js +6 -6
  22. package/dist/boilerplates/@batijs/eslint/files/eslint.config.ts +5 -5
  23. package/dist/boilerplates/@batijs/express/files/$package.json.js +7 -7
  24. package/dist/boilerplates/@batijs/express/files/express-entry.ts +0 -24
  25. package/dist/boilerplates/@batijs/fastify/files/$package.json.js +8 -8
  26. package/dist/boilerplates/@batijs/fastify/files/fastify-entry.ts +0 -24
  27. package/dist/boilerplates/@batijs/firebase-auth/files/$.env.js +3 -3
  28. package/dist/boilerplates/@batijs/firebase-auth/files/$README.md.js +3 -3
  29. package/dist/boilerplates/@batijs/firebase-auth/files/$package.json.js +6 -6
  30. package/dist/boilerplates/@batijs/google-analytics/files/$.env.js +3 -3
  31. package/dist/boilerplates/@batijs/h3/files/$package.json.js +7 -7
  32. package/dist/boilerplates/@batijs/h3/files/h3-entry.ts +0 -24
  33. package/dist/boilerplates/@batijs/hattip/files/$package.json.js +7 -7
  34. package/dist/boilerplates/@batijs/hattip/files/hattip-entry.ts +0 -24
  35. package/dist/boilerplates/@batijs/hono/files/$package.json.js +8 -8
  36. package/dist/boilerplates/@batijs/hono/files/$vite.config.ts.js +5 -5
  37. package/dist/boilerplates/@batijs/hono/files/hono-entry.ts +0 -24
  38. package/dist/boilerplates/@batijs/mantine/files/$README.md.js +3 -3
  39. package/dist/boilerplates/@batijs/mantine/files/$package.json.js +8 -8
  40. package/dist/boilerplates/@batijs/panda-css/files/$package.json.js +6 -6
  41. package/dist/boilerplates/@batijs/pnpm/files/$pnpm-workspace.yaml.js +3 -3
  42. package/dist/boilerplates/@batijs/prettier/files/$package.json.js +4 -4
  43. package/dist/boilerplates/@batijs/prisma/files/$.env.js +3 -3
  44. package/dist/boilerplates/@batijs/prisma/files/$README.md.js +3 -3
  45. package/dist/boilerplates/@batijs/prisma/files/$package.json.js +4 -4
  46. package/dist/boilerplates/@batijs/react/files/$README.md.js +3 -3
  47. package/dist/boilerplates/@batijs/react/files/$package.json.js +9 -9
  48. package/dist/boilerplates/@batijs/react/files/$tsconfig.json.js +3 -3
  49. package/dist/boilerplates/@batijs/react/files/$vite.config.ts.js +5 -5
  50. package/dist/boilerplates/@batijs/react/files/layouts/LayoutDefault.tsx +1 -1
  51. package/dist/boilerplates/@batijs/react/files/pages/+config.ts +1 -1
  52. package/dist/boilerplates/@batijs/react-sentry/files/$package.json.js +6 -6
  53. package/dist/boilerplates/@batijs/sentry/files/$.env.js +4 -4
  54. package/dist/boilerplates/@batijs/sentry/files/$README.md.js +3 -3
  55. package/dist/boilerplates/@batijs/sentry/files/$package.json.js +4 -4
  56. package/dist/boilerplates/@batijs/sentry/files/$vite.config.ts.js +7 -7
  57. package/dist/boilerplates/@batijs/sentry/files/pages/$+client.ts.js +7 -7
  58. package/dist/boilerplates/@batijs/shadcn-ui/files/$README.md.js +3 -3
  59. package/dist/boilerplates/@batijs/shadcn-ui/files/$package.json.js +7 -7
  60. package/dist/boilerplates/@batijs/shadcn-ui/files/$tsconfig.json.js +3 -3
  61. package/dist/boilerplates/@batijs/shadcn-ui/files/$vite.config.ts.js +5 -5
  62. package/dist/boilerplates/@batijs/shared/files/$README.md.js +9 -9
  63. package/dist/boilerplates/@batijs/shared-server/files/$package.json.js +6 -6
  64. package/dist/boilerplates/@batijs/solid/files/$README.md.js +3 -3
  65. package/dist/boilerplates/@batijs/solid/files/$package.json.js +6 -6
  66. package/dist/boilerplates/@batijs/solid/files/$tsconfig.json.js +3 -3
  67. package/dist/boilerplates/@batijs/solid/files/$vite.config.ts.js +5 -5
  68. package/dist/boilerplates/@batijs/solid/files/layouts/LayoutDefault.tsx +1 -1
  69. package/dist/boilerplates/@batijs/solid/files/pages/+config.ts +1 -1
  70. package/dist/boilerplates/@batijs/solid-sentry/files/$package.json.js +5 -5
  71. package/dist/boilerplates/@batijs/sqlite/files/$.env.js +3 -3
  72. package/dist/boilerplates/@batijs/sqlite/files/$README.md.js +3 -3
  73. package/dist/boilerplates/@batijs/sqlite/files/$package.json.js +5 -17
  74. package/dist/boilerplates/@batijs/sqlite/files/database/sqlite/schema/all.ts +0 -2
  75. package/dist/boilerplates/@batijs/sqlite/types/database/sqlite/schema/all.d.ts +0 -1
  76. package/dist/boilerplates/@batijs/tailwindcss/files/$package.json.js +6 -6
  77. package/dist/boilerplates/@batijs/tailwindcss/files/$vite.config.ts.js +5 -5
  78. package/dist/boilerplates/@batijs/telefunc/files/$package.json.js +6 -6
  79. package/dist/boilerplates/@batijs/telefunc/files/$vite.config.ts.js +5 -5
  80. package/dist/boilerplates/@batijs/trpc/files/$package.json.js +8 -8
  81. package/dist/boilerplates/@batijs/trpc/types/trpc/client.d.ts +3 -3
  82. package/dist/boilerplates/@batijs/trpc/types/trpc/server.d.ts +8 -8
  83. package/dist/boilerplates/@batijs/ts-rest/files/$package.json.js +7 -7
  84. package/dist/boilerplates/@batijs/vercel/files/$package.json.js +4 -4
  85. package/dist/boilerplates/@batijs/vercel/files/$tsconfig.json.js +3 -3
  86. package/dist/boilerplates/@batijs/vercel/files/$vite.config.ts.js +5 -5
  87. package/dist/boilerplates/@batijs/vercel/files/pages/$+config.ts.js +3 -3
  88. package/dist/boilerplates/@batijs/vue/files/$README.md.js +3 -3
  89. package/dist/boilerplates/@batijs/vue/files/$package.json.js +6 -6
  90. package/dist/boilerplates/@batijs/vue/files/$tsconfig.json.js +3 -3
  91. package/dist/boilerplates/@batijs/vue/files/$vite.config.ts.js +6 -6
  92. package/dist/boilerplates/@batijs/vue/files/layouts/LayoutDefault.vue +1 -1
  93. package/dist/boilerplates/@batijs/vue/files/pages/+config.ts +1 -1
  94. package/dist/boilerplates/@batijs/vue-sentry/files/$package.json.js +5 -5
  95. package/dist/boilerplates/boilerplates.json +0 -59
  96. package/dist/{chunk-4WNEELKU.js → chunk-YO6CY4MA.js} +53461 -53354
  97. package/dist/index.js +63 -92
  98. package/package.json +6 -6
  99. package/dist/boilerplates/@batijs/d1-sqlite/files/database/d1/queries/lucia-auth.ts +0 -29
  100. package/dist/boilerplates/@batijs/d1-sqlite/files/database/migrations/lucia-auth.sql +0 -20
  101. package/dist/boilerplates/@batijs/d1-sqlite/types/database/d1/queries/lucia-auth.d.ts +0 -5
  102. package/dist/boilerplates/@batijs/drizzle/files/database/drizzle/queries/lucia-auth.ts +0 -56
  103. package/dist/boilerplates/@batijs/drizzle/files/database/drizzle/schema/lucia-auth.ts +0 -41
  104. package/dist/boilerplates/@batijs/drizzle/types/database/drizzle/queries/lucia-auth.d.ts +0 -25
  105. package/dist/boilerplates/@batijs/drizzle/types/database/drizzle/schema/lucia-auth.d.ts +0 -190
  106. package/dist/boilerplates/@batijs/lucia-auth/files/$.env.js +0 -32
  107. package/dist/boilerplates/@batijs/lucia-auth/files/$README.md.js +0 -38
  108. package/dist/boilerplates/@batijs/lucia-auth/files/$package.json.js +0 -113
  109. package/dist/boilerplates/@batijs/lucia-auth/files/global.d.ts +0 -11
  110. package/dist/boilerplates/@batijs/lucia-auth/files/lib/lucia-auth.ts +0 -136
  111. package/dist/boilerplates/@batijs/lucia-auth/files/pages/login/+guard.ts +0 -11
  112. package/dist/boilerplates/@batijs/lucia-auth/files/pages/login/style.css +0 -94
  113. package/dist/boilerplates/@batijs/lucia-auth/files/server/lucia-auth-handlers.ts +0 -401
  114. package/dist/boilerplates/@batijs/lucia-auth/types/lib/lucia-auth.d.ts +0 -63
  115. package/dist/boilerplates/@batijs/lucia-auth/types/pages/login/+guard.d.ts +0 -3
  116. package/dist/boilerplates/@batijs/lucia-auth/types/server/lucia-auth-handlers.d.ts +0 -65
  117. package/dist/boilerplates/@batijs/react-lucia-auth/files/pages/login/+Page.tsx +0 -97
  118. package/dist/boilerplates/@batijs/react-lucia-auth/types/pages/login/+Page.d.ts +0 -2
  119. package/dist/boilerplates/@batijs/solid-lucia-auth/files/pages/login/+Page.tsx +0 -97
  120. package/dist/boilerplates/@batijs/solid-lucia-auth/types/pages/login/+Page.d.ts +0 -2
  121. package/dist/boilerplates/@batijs/sqlite/files/database/sqlite/queries/lucia-auth.ts +0 -27
  122. package/dist/boilerplates/@batijs/sqlite/files/database/sqlite/schema/lucia-auth.ts +0 -32
  123. package/dist/boilerplates/@batijs/sqlite/types/database/sqlite/queries/lucia-auth.d.ts +0 -5
  124. package/dist/boilerplates/@batijs/sqlite/types/database/sqlite/schema/lucia-auth.d.ts +0 -1
  125. package/dist/boilerplates/@batijs/vue-lucia-auth/files/pages/login/+Page.vue +0 -88
@@ -1,401 +0,0 @@
1
- import type { Session, User } from "lucia";
2
- import { generateId, Scrypt, verifyRequestOrigin } from "lucia";
3
- import {
4
- type DatabaseOAuthAccount,
5
- type DatabaseUser,
6
- github,
7
- type GitHubUser,
8
- initializeLucia,
9
- } from "../lib/lucia-auth";
10
- import { SqliteError } from "better-sqlite3";
11
- import { generateState, OAuth2RequestError } from "arctic";
12
- import { parse, serialize } from "cookie";
13
- import * as drizzleQueries from "@batijs/drizzle/database/drizzle/queries/lucia-auth";
14
- import * as sqliteQueries from "@batijs/sqlite/database/sqlite/queries/lucia-auth";
15
- import * as d1Queries from "@batijs/d1-sqlite/database/d1/queries/lucia-auth";
16
- // TODO: stop using universal-middleware and directly integrate server middlewares instead and/or use vike-server https://vike.dev/server. (Bati generates boilerplates that use universal-middleware https://github.com/magne4000/universal-middleware to make Bati's internal logic easier. This is temporary and will be removed soon.)
17
- import { type Get, type UniversalHandler, type UniversalMiddleware } from "@universal-middleware/core";
18
-
19
- /**
20
- * Add lucia database to the context
21
- *
22
- * @link {@see https://universal-middleware.dev/examples/context-middleware}
23
- */
24
- export const luciaDbMiddleware: Get<[], UniversalMiddleware> = () => async (_request, context, _runtime) => {
25
- const lucia = initializeLucia(context.db);
26
- return {
27
- ...context,
28
- lucia,
29
- };
30
- };
31
-
32
- /**
33
- * CSRF protection middleware
34
- *
35
- * @link {@see https://lucia-auth.com/guides/validate-session-cookies/}
36
- */
37
- export const luciaCsrfMiddleware = (() => async (request) => {
38
- if (request.method === "GET") {
39
- return;
40
- }
41
- if (!BATI_TEST) {
42
- const originHeader = request.headers.get("Origin") ?? null;
43
- const hostHeader = request.headers.get("Host") ?? null;
44
-
45
- if (!originHeader || !hostHeader || !verifyRequestOrigin(originHeader, [hostHeader])) {
46
- return new Response("Forbidden Request", {
47
- status: 403,
48
- });
49
- }
50
- }
51
- }) satisfies Get<[], UniversalMiddleware>;
52
-
53
- /**
54
- * Validate session cookies middleware and set context
55
- *
56
- * @link {@see https://lucia-auth.com/guides/validate-session-cookies/}
57
- */
58
- export const luciaAuthContextMiddleware: Get<[], UniversalMiddleware> = () => async (request, context) => {
59
- const sessionId = context.lucia.readSessionCookie(request.headers.get("cookie") ?? "");
60
-
61
- if (!sessionId) {
62
- return {
63
- ...context,
64
- session: null,
65
- user: null,
66
- };
67
- } else {
68
- const { session, user } = await context.lucia.validateSession(sessionId);
69
-
70
- return {
71
- ...context,
72
- sessionId,
73
- session,
74
- user,
75
- };
76
- }
77
- };
78
-
79
- /**
80
- * Set Set-Cookie headers if in context
81
- */
82
- export const luciaAuthCookieMiddleware = (() => (_request, context) => {
83
- return (response: Response) => {
84
- if (context.session?.fresh) {
85
- response.headers.append("Set-Cookie", context.lucia.createSessionCookie(context.session.id).serialize());
86
- }
87
- if (context.sessionId && !context.session) {
88
- response.headers.append("Set-Cookie", context.lucia.createBlankSessionCookie().serialize());
89
- }
90
-
91
- return response;
92
- };
93
- }) satisfies Get<
94
- [],
95
- UniversalMiddleware<Universal.Context & { session?: Session | null; user?: User | null; sessionId?: string | null }>
96
- >;
97
-
98
- /**
99
- * Register user handler
100
- *
101
- * @link {@see https://lucia-auth.com/guides/email-and-password/basics#register-user}
102
- */
103
- export const luciaAuthSignupHandler = (() => async (request, context, _runtime) => {
104
- const body = (await request.json()) as { username: string; password: string };
105
- const username = body.username ?? "";
106
- const password = body.password ?? "";
107
-
108
- const validated = validateInput(username, password);
109
-
110
- if (!validated.success) {
111
- return new Response(JSON.stringify({ error: validated.error }), {
112
- status: 422,
113
- headers: {
114
- "content-type": "application/json",
115
- },
116
- });
117
- }
118
-
119
- /**
120
- * A pure JS implementation of Scrypt.
121
- * It's portable but slower than implementations based on native code.
122
- *
123
- * @link {@see https://lucia-auth.com/reference/main/Scrypt}
124
- * @link {@see https://lucia-auth.com/guides/email-and-password/basics#hashing-passwords}
125
- */
126
- const scrypt = new Scrypt();
127
- const passwordHash = await scrypt.hash(password);
128
-
129
- const userId = generateId(15);
130
-
131
- try {
132
- if (BATI.has("drizzle")) {
133
- await drizzleQueries.signupWithCredentials(context.db, userId, username, passwordHash);
134
- } else if (BATI.has("sqlite") && !BATI.hasD1) {
135
- sqliteQueries.signupWithCredentials(context.db, userId, username, passwordHash);
136
- } else if (BATI.hasD1) {
137
- await d1Queries.signupWithCredentials(context.db, userId, username, passwordHash);
138
- }
139
-
140
- const session = await context.lucia.createSession(userId, {});
141
-
142
- return new Response(JSON.stringify({ status: "success" }), {
143
- status: 200,
144
- headers: {
145
- "content-type": "application/json",
146
- "set-cookie": context.lucia.createSessionCookie(session.id).serialize(),
147
- },
148
- });
149
- } catch (error) {
150
- console.error(error);
151
- if (BATI.has("sqlite") && !BATI.hasD1) {
152
- if (error instanceof SqliteError && error.code === "SQLITE_CONSTRAINT_UNIQUE") {
153
- return new Response(JSON.stringify({ error: { username: "Username already in use" } }), {
154
- status: 422,
155
- headers: {
156
- "content-type": "application/json",
157
- },
158
- });
159
- }
160
- }
161
-
162
- return new Response(JSON.stringify({ error: { invalid: "An unknown error has occurred" } }), {
163
- status: 500,
164
- headers: {
165
- "content-type": "application/json",
166
- },
167
- });
168
- }
169
- }) satisfies Get<[], UniversalMiddleware>;
170
-
171
- /**
172
- * Sign in user handler
173
- *
174
- * @link {@see https://lucia-auth.com/guides/email-and-password/basics#sign-in-user}
175
- */
176
- export const luciaAuthLoginHandler = (() => async (request, context, _runtime) => {
177
- const body = (await request.json()) as { username: string; password: string };
178
- const username = body.username ?? "";
179
- const password = body.password ?? "";
180
-
181
- const validated = validateInput(username, password);
182
-
183
- if (!validated.success) {
184
- return new Response(JSON.stringify({ error: validated.error }), {
185
- status: 422,
186
- headers: {
187
- "content-type": "application/json",
188
- },
189
- });
190
- }
191
-
192
- const existingUser: DatabaseUser | undefined | null = BATI.has("drizzle")
193
- ? await drizzleQueries.getExistingUser(context.db, username)
194
- : BATI.has("sqlite") && !BATI.hasD1
195
- ? sqliteQueries.getExistingUser<DatabaseUser>(context.db, username)
196
- : BATI.hasD1
197
- ? await d1Queries.getExistingUser<DatabaseUser>(context.db, username)
198
- : undefined;
199
-
200
- if (!existingUser) {
201
- return new Response(JSON.stringify({ error: { invalid: "Incorrect username or password" } }), {
202
- status: 422,
203
- headers: {
204
- "content-type": "application/json",
205
- },
206
- });
207
- }
208
-
209
- const scrypt = new Scrypt();
210
- const validPassword = existingUser.password && (await scrypt.verify(existingUser.password, password));
211
-
212
- if (!validPassword) {
213
- return new Response(JSON.stringify({ error: { invalid: "Incorrect username or password" } }), {
214
- status: 422,
215
- headers: {
216
- "content-type": "application/json",
217
- },
218
- });
219
- }
220
-
221
- const session = await context.lucia.createSession(existingUser.id, {});
222
-
223
- return new Response(JSON.stringify({ status: "success" }), {
224
- status: 200,
225
- headers: {
226
- "content-type": "application/json",
227
- "set-cookie": context.lucia.createSessionCookie(session.id).serialize(),
228
- },
229
- });
230
- }) satisfies Get<[], UniversalMiddleware>;
231
-
232
- /**
233
- * Log out user handler
234
- */
235
- export const luciaAuthLogoutHandler = (() => async (_request, context) => {
236
- const session = context.session ?? null;
237
-
238
- if (!session) {
239
- return new Response("Unauthorized Request", {
240
- status: 401,
241
- });
242
- }
243
- /**
244
- * Invalidate sessions
245
- *
246
- * @link {@see https://lucia-auth.com/basics/sessions#invalidate-sessions}
247
- */
248
- await context.lucia.invalidateSession(session.id);
249
-
250
- /**
251
- * Delete session cookie
252
- *
253
- * @link {@see https://lucia-auth.com/basics/sessions#delete-session-cookie}
254
- */
255
- return new Response(JSON.stringify({ status: "success" }), {
256
- status: 200,
257
- headers: {
258
- "set-cookie": context.lucia.createBlankSessionCookie().serialize(),
259
- },
260
- });
261
- }) satisfies Get<[], UniversalMiddleware<Universal.Context & { session?: Session | null }>>;
262
-
263
- /**
264
- * Github OAuth authorization handler
265
- *
266
- * @link {@see https://lucia-auth.com/guides/oauth/basics#creating-authorization-url}
267
- */
268
- export const luciaGithubLoginHandler = (() => async () => {
269
- const state = generateState();
270
- const url = github.createAuthorizationURL(state, ["user:email"]);
271
-
272
- return new Response(null, {
273
- status: 302,
274
- headers: {
275
- Location: url.toString(),
276
- "set-cookie": serialize("github_oauth_state", state, {
277
- path: "/",
278
- secure: process.env.NODE_ENV === "production",
279
- httpOnly: true,
280
- maxAge: 60 * 10,
281
- sameSite: "lax",
282
- }),
283
- },
284
- });
285
- }) satisfies Get<[], UniversalHandler>;
286
-
287
- /**
288
- * Github OAuth validate callback handler
289
- *
290
- * @link {@see https://lucia-auth.com/guides/oauth/basics#validate-callback}
291
- */
292
- export const luciaGithubCallbackHandler = (() => async (request, context, _runtime) => {
293
- const cookies = parse(request.headers.get("cookie") ?? "");
294
- const params = new URL(request.url).searchParams;
295
- const code = params.get("code");
296
- const state = params.get("state");
297
- const storedState = cookies.github_oauth_state ?? null;
298
-
299
- if (!code || !state || !storedState || state !== storedState) {
300
- return new Response("Unauthorized Request", {
301
- status: 401,
302
- });
303
- }
304
-
305
- try {
306
- const tokens = await github.validateAuthorizationCode(code);
307
- const githubUserResponse = await fetch("https://api.github.com/user", {
308
- headers: {
309
- Authorization: `Bearer ${tokens.accessToken}`,
310
- },
311
- });
312
- const githubUser = (await githubUserResponse.json()) as GitHubUser;
313
-
314
- const existingAccount: DatabaseOAuthAccount | undefined | null = BATI.has("drizzle")
315
- ? ((await drizzleQueries.getExistingAccount(context.db, "github", githubUser.id)) as
316
- | DatabaseOAuthAccount
317
- | undefined)
318
- : BATI.has("sqlite") && !BATI.hasD1
319
- ? sqliteQueries.getExistingAccount<DatabaseOAuthAccount>(context.db, "github", githubUser.id)
320
- : BATI.hasD1
321
- ? await d1Queries.getExistingAccount<DatabaseOAuthAccount>(context.db, "github", githubUser.id)
322
- : undefined;
323
-
324
- if (existingAccount) {
325
- const session = await context.lucia.createSession(
326
- BATI.has("drizzle") ? existingAccount.userId : existingAccount.user_id,
327
- {},
328
- );
329
- return new Response(null, {
330
- status: 302,
331
- headers: {
332
- Location: "/",
333
- "set-cookie": context.lucia.createSessionCookie(session.id).serialize(),
334
- },
335
- });
336
- }
337
-
338
- const userId = generateId(15);
339
-
340
- if (BATI.has("drizzle")) {
341
- await drizzleQueries.signupWithGithub(context.db, userId, githubUser.login, githubUser.id);
342
- } else if (BATI.has("sqlite") && !BATI.hasD1) {
343
- sqliteQueries.signupWithGithub(context.db, userId, githubUser.login, githubUser.id);
344
- } else if (BATI.hasD1) {
345
- await d1Queries.signupWithGithub(context.db, userId, githubUser.login, githubUser.id);
346
- }
347
-
348
- const session = await context.lucia.createSession(userId, {});
349
-
350
- return new Response(null, {
351
- status: 302,
352
- headers: {
353
- Location: "/",
354
- "set-cookie": context.lucia.createSessionCookie(session.id).serialize(),
355
- },
356
- });
357
- } catch (error) {
358
- if (error instanceof OAuth2RequestError && error.message === "bad_verification_code") {
359
- return new Response(JSON.stringify({ error: error.message }), {
360
- status: 400,
361
- headers: {
362
- "content-type": "application/json",
363
- },
364
- });
365
- }
366
- return new Response(JSON.stringify({ error: error }), {
367
- status: 500,
368
- headers: {
369
- "content-type": "application/json",
370
- },
371
- });
372
- }
373
- }) satisfies Get<[], UniversalHandler>;
374
-
375
- export function validateInput(username: string | null, password: string | null) {
376
- const error: {
377
- username: string | null;
378
- password: string | null;
379
- } = {
380
- username: null,
381
- password: null,
382
- };
383
-
384
- if (!username || username.length < 3 || username.length > 31 || !/^[a-z0-9_-]+$/.test(username)) {
385
- error.username = "Invalid username";
386
- }
387
- if (!password || password.length < 6 || password.length > 255) {
388
- error.password = "Invalid password";
389
- }
390
-
391
- if (error.username || error.password) {
392
- return {
393
- error,
394
- success: false,
395
- };
396
- }
397
- return {
398
- error,
399
- success: true,
400
- };
401
- }
@@ -1,63 +0,0 @@
1
- import "dotenv/config";
2
- import { Lucia, type Register } from "lucia";
3
- import { GitHub } from "arctic";
4
- import { dbD1, dbSqlite } from "@batijs/drizzle/database/drizzle/db";
5
- import { db as sqliteDb } from "@batijs/sqlite/database/sqlite/db";
6
- import { D1Database } from "@cloudflare/workers-types";
7
- export declare function initializeLucia(db: BATI.If<{
8
- 'BATI.has("sqlite") && !BATI.hasD1': ReturnType<typeof sqliteDb>;
9
- 'BATI.has("drizzle") && !BATI.hasD1': ReturnType<typeof dbSqlite>;
10
- 'BATI.has("drizzle")': ReturnType<typeof dbD1>;
11
- "BATI.hasD1": D1Database;
12
- }, "union">): Lucia<Record<never, never>, {
13
- username: string;
14
- }>;
15
- /**
16
- * Initialize OAuth provider
17
- *
18
- * @link {@see https://lucia-auth.com/guides/oauth/basics#initialize-oauth-provider}
19
- */
20
- export declare const github: GitHub;
21
- /**
22
- * Define user attributes
23
- *
24
- * @link {@see https://lucia-auth.com/basics/users#define-user-attributes}
25
- */
26
- declare module "lucia" {
27
- interface Register {
28
- Lucia: ReturnType<typeof initializeLucia>;
29
- DatabaseUserAttributes: Omit<DatabaseUser, "id">;
30
- }
31
- }
32
- declare global {
33
- namespace Universal {
34
- interface Context {
35
- lucia: Register["Lucia"];
36
- db: BATI.If<{
37
- 'BATI.has("sqlite") && !BATI.hasD1': ReturnType<typeof sqliteDb>;
38
- 'BATI.has("drizzle") && !BATI.hasD1': ReturnType<typeof dbSqlite>;
39
- 'BATI.has("drizzle")': ReturnType<typeof dbD1>;
40
- "BATI.hasD1": D1Database;
41
- }>;
42
- }
43
- }
44
- }
45
- export interface DatabaseUser {
46
- id: string;
47
- username: string;
48
- password?: string | null;
49
- }
50
- export interface DatabaseOAuthAccount {
51
- provider_id: string;
52
- provider_user_id: string;
53
- user_id: string;
54
- }
55
- export interface DatabaseOAuthAccount {
56
- providerId: string;
57
- providerUserId: string;
58
- userId: string;
59
- }
60
- export interface GitHubUser {
61
- id: number;
62
- login: string;
63
- }
@@ -1,3 +0,0 @@
1
- import type { GuardAsync } from "vike/types";
2
- declare const guard: GuardAsync;
3
- export { guard };
@@ -1,65 +0,0 @@
1
- import type { Session, User } from "lucia";
2
- import { type Get, type UniversalMiddleware } from "@universal-middleware/core";
3
- /**
4
- * Add lucia database to the context
5
- *
6
- * @link {@see https://universal-middleware.dev/examples/context-middleware}
7
- */
8
- export declare const luciaDbMiddleware: Get<[], UniversalMiddleware>;
9
- /**
10
- * CSRF protection middleware
11
- *
12
- * @link {@see https://lucia-auth.com/guides/validate-session-cookies/}
13
- */
14
- export declare const luciaCsrfMiddleware: () => (request: Request) => Promise<Response | undefined>;
15
- /**
16
- * Validate session cookies middleware and set context
17
- *
18
- * @link {@see https://lucia-auth.com/guides/validate-session-cookies/}
19
- */
20
- export declare const luciaAuthContextMiddleware: Get<[], UniversalMiddleware>;
21
- /**
22
- * Set Set-Cookie headers if in context
23
- */
24
- export declare const luciaAuthCookieMiddleware: () => (_request: Request, context: Universal.Context & {
25
- session?: Session | null;
26
- user?: User | null;
27
- sessionId?: string | null;
28
- }) => (response: Response) => Response;
29
- /**
30
- * Register user handler
31
- *
32
- * @link {@see https://lucia-auth.com/guides/email-and-password/basics#register-user}
33
- */
34
- export declare const luciaAuthSignupHandler: () => (request: Request, context: Universal.Context, _runtime: import("@universal-middleware/core").RuntimeAdapter) => Promise<Response>;
35
- /**
36
- * Sign in user handler
37
- *
38
- * @link {@see https://lucia-auth.com/guides/email-and-password/basics#sign-in-user}
39
- */
40
- export declare const luciaAuthLoginHandler: () => (request: Request, context: Universal.Context, _runtime: import("@universal-middleware/core").RuntimeAdapter) => Promise<Response>;
41
- /**
42
- * Log out user handler
43
- */
44
- export declare const luciaAuthLogoutHandler: () => (_request: Request, context: Universal.Context & {
45
- session?: Session | null;
46
- }) => Promise<Response>;
47
- /**
48
- * Github OAuth authorization handler
49
- *
50
- * @link {@see https://lucia-auth.com/guides/oauth/basics#creating-authorization-url}
51
- */
52
- export declare const luciaGithubLoginHandler: () => () => Promise<Response>;
53
- /**
54
- * Github OAuth validate callback handler
55
- *
56
- * @link {@see https://lucia-auth.com/guides/oauth/basics#validate-callback}
57
- */
58
- export declare const luciaGithubCallbackHandler: () => (request: Request, context: Universal.Context, _runtime: import("@universal-middleware/core").RuntimeAdapter) => Promise<Response>;
59
- export declare function validateInput(username: string | null, password: string | null): {
60
- error: {
61
- username: string | null;
62
- password: string | null;
63
- };
64
- success: boolean;
65
- };
@@ -1,97 +0,0 @@
1
- import "./style.css";
2
- import { useState } from "react";
3
- import { navigate } from "vike/client/router";
4
-
5
- type ValidationError = { username: string | null; password: string | null; invalid?: string };
6
-
7
- export default function Page() {
8
- const [formData, setFormData] = useState({
9
- username: "",
10
- password: "",
11
- });
12
-
13
- const [error, setError] = useState<ValidationError>({
14
- username: null,
15
- password: null,
16
- });
17
-
18
- const handleOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
19
- const { name, value } = e.target;
20
- setFormData((prev) => ({ ...prev, [name]: value }));
21
- };
22
- const handleOnSubmit = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>, action: "login" | "signup") => {
23
- e.preventDefault();
24
- try {
25
- const response = await fetch(`/api/${action}`, {
26
- method: "POST",
27
- body: JSON.stringify(formData),
28
- headers: { "Content-Type": "application/json" },
29
- });
30
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
- const result: Record<string, any> = await response.json();
32
- if ("error" in result) {
33
- console.error("A validation error has occurred :", result.error);
34
- setError(result.error);
35
- } else {
36
- await navigate("/");
37
- }
38
- } catch (err) {
39
- console.error("An unknown error has occurred :", err);
40
- }
41
- };
42
-
43
- return (
44
- <div className="form">
45
- <div className="form-content">
46
- <header>Login / Sign Up</header>
47
- <form>
48
- <div className="field">
49
- <input
50
- id="username"
51
- type="text"
52
- name="username"
53
- value={formData.username}
54
- onChange={handleOnChange}
55
- placeholder="Username"
56
- autoComplete="username"
57
- />
58
- </div>
59
- {error.username && <span className="field-error">{error.username}</span>}
60
-
61
- <div className="field">
62
- <input
63
- id="password"
64
- type="password"
65
- name="password"
66
- value={formData.password}
67
- onChange={handleOnChange}
68
- placeholder="Password"
69
- />
70
- </div>
71
- {error.password && <span className="field-error">{error.password}</span>}
72
- {error.invalid && <span className="field-error">{error.invalid}</span>}
73
-
74
- <div className="field button-group">
75
- <button type="button" className="button-field signup-button" onClick={(e) => handleOnSubmit(e, "signup")}>
76
- Sign Up
77
- </button>
78
- <button type="submit" className="button-field login-button" onClick={(e) => handleOnSubmit(e, "login")}>
79
- Login
80
- </button>
81
- </div>
82
- </form>
83
- </div>
84
-
85
- <div className="media-options">
86
- <a href="/api/login/github" className="field github">
87
- <img
88
- src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA0OTYgNTEyJz48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNi4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjQgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0nTTE2NS45IDM5Ny40YzAgMi0yLjMgMy42LTUuMiAzLjYtMy4zIC4zLTUuNi0xLjMtNS42LTMuNiAwLTIgMi4zLTMuNiA1LjItMy42IDMtLjMgNS42IDEuMyA1LjYgMy42em0tMzEuMS00LjVjLS43IDIgMS4zIDQuMyA0LjMgNC45IDIuNiAxIDUuNiAwIDYuMi0ycy0xLjMtNC4zLTQuMy01LjJjLTIuNi0uNy01LjUgLjMtNi4yIDIuM3ptNDQuMi0xLjdjLTIuOSAuNy00LjkgMi42LTQuNiA0LjkgLjMgMiAyLjkgMy4zIDUuOSAyLjYgMi45LS43IDQuOS0yLjYgNC42LTQuNi0uMy0xLjktMy0zLjItNS45LTIuOXpNMjQ0LjggOEMxMDYuMSA4IDAgMTEzLjMgMCAyNTJjMCAxMTAuOSA2OS44IDIwNS44IDE2OS41IDIzOS4yIDEyLjggMi4zIDE3LjMtNS42IDE3LjMtMTIuMSAwLTYuMi0uMy00MC40LS4zLTYxLjQgMCAwLTcwIDE1LTg0LjctMjkuOCAwIDAtMTEuNC0yOS4xLTI3LjgtMzYuNiAwIDAtMjIuOS0xNS43IDEuNi0xNS40IDAgMCAyNC45IDIgMzguNiAyNS44IDIxLjkgMzguNiA1OC42IDI3LjUgNzIuOSAyMC45IDIuMy0xNiA4LjgtMjcuMSAxNi0zMy43LTU1LjktNi4yLTExMi4zLTE0LjMtMTEyLjMtMTEwLjUgMC0yNy41IDcuNi00MS4zIDIzLjYtNTguOS0yLjYtNi41LTExLjEtMzMuMyAyLjYtNjcuOSAyMC45LTYuNSA2OSAyNyA2OSAyNyAyMC01LjYgNDEuNS04LjUgNjIuOC04LjVzNDIuOCAyLjkgNjIuOCA4LjVjMCAwIDQ4LjEtMzMuNiA2OS0yNyAxMy43IDM0LjcgNS4yIDYxLjQgMi42IDY3LjkgMTYgMTcuNyAyNS44IDMxLjUgMjUuOCA1OC45IDAgOTYuNS01OC45IDEwNC4yLTExNC44IDExMC41IDkuMiA3LjkgMTcgMjIuOSAxNyA0Ni40IDAgMzMuNy0uMyA3NS40LS4zIDgzLjYgMCA2LjUgNC42IDE0LjQgMTcuMyAxMi4xQzQyOC4yIDQ1Ny44IDQ5NiAzNjIuOSA0OTYgMjUyIDQ5NiAxMTMuMyAzODMuNSA4IDI0NC44IDh6TTk3LjIgMzUyLjljLTEuMyAxLTEgMy4zIC43IDUuMiAxLjYgMS42IDMuOSAyLjMgNS4yIDEgMS4zLTEgMS0zLjMtLjctNS4yLTEuNi0xLjYtMy45LTIuMy01LjItMXptLTEwLjgtOC4xYy0uNyAxLjMgLjMgMi45IDIuMyAzLjkgMS42IDEgMy42IC43IDQuMy0uNyAuNy0xLjMtLjMtMi45LTIuMy0zLjktMi0uNi0zLjYtLjMtNC4zIC43em0zMi40IDM1LjZjLTEuNiAxLjMtMSA0LjMgMS4zIDYuMiAyLjMgMi4zIDUuMiAyLjYgNi41IDEgMS4zLTEuMyAuNy00LjMtMS4zLTYuMi0yLjItMi4zLTUuMi0yLjYtNi41LTF6bS0xMS40LTE0LjdjLTEuNiAxLTEuNiAzLjYgMCA1LjkgMS42IDIuMyA0LjMgMy4zIDUuNiAyLjMgMS42LTEuMyAxLjYtMy45IDAtNi4yLTEuNC0yLjMtNC0zLjMtNS42LTJ6Jy8+PC9zdmc+"
89
- className="github-icon"
90
- alt=""
91
- />
92
- <span>Login with Github</span>
93
- </a>
94
- </div>
95
- </div>
96
- );
97
- }
@@ -1,2 +0,0 @@
1
- import "./style.css";
2
- export default function Page(): import("react/jsx-runtime").JSX.Element;