better-auth 0.2.8-beta.8 → 0.2.8
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/dist/.DS_Store +0 -0
- package/dist/access.js +13 -2
- package/dist/adapters/drizzle.d.ts +1 -1
- package/dist/adapters/drizzle.js +13 -23
- package/dist/adapters/mongodb.d.ts +1 -1
- package/dist/adapters/mongodb.js +3 -2
- package/dist/adapters/prisma.d.ts +1 -1
- package/dist/adapters/prisma.js +3 -280
- package/dist/api.d.ts +1 -1
- package/dist/api.js +407 -269
- package/dist/cli.js +213 -55
- package/dist/client/plugins.d.ts +5 -3
- package/dist/client/plugins.js +49 -34
- package/dist/client.d.ts +3 -1
- package/dist/client.js +34 -32
- package/dist/{index-CKn-Zrry.d.ts → index-C9S3KShG.d.ts} +50 -63
- package/dist/{index-DtRHPoYF.d.ts → index-UOcOxfoL.d.ts} +6 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +501 -372
- package/dist/next-js.d.ts +1 -1
- package/dist/next-js.js +6 -5
- package/dist/node.d.ts +1 -1
- package/dist/node.js +5 -5
- package/dist/plugins.d.ts +8 -5
- package/dist/plugins.js +716 -498
- package/dist/react.d.ts +4 -2
- package/dist/react.js +37 -33
- package/dist/social.js +116 -68
- package/dist/solid-start.d.ts +1 -1
- package/dist/solid-start.js +3 -2
- package/dist/solid.d.ts +2 -1
- package/dist/solid.js +35 -32
- package/dist/svelte-kit.d.ts +1 -1
- package/dist/svelte-kit.js +6 -4
- package/dist/svelte.d.ts +2 -1
- package/dist/svelte.js +33 -32
- package/dist/types.d.ts +2 -2
- package/dist/types.js +0 -1
- package/dist/vue.d.ts +3 -1
- package/dist/vue.js +35 -32
- package/package.json +2 -3
- package/dist/hide-metadata-DEHJp1rk.d.ts +0 -5
- package/dist/utils.d.ts +0 -51
- package/dist/utils.js +0 -426
package/dist/plugins.js
CHANGED
|
@@ -1,29 +1,21 @@
|
|
|
1
|
-
import { createMiddleware, createMiddlewareCreator, createEndpointCreator, APIError, serializeSigned } from 'better-call';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { generateCodeVerifier, generateState as generateState$1 } from 'oslo/oauth2';
|
|
4
|
-
import { Facebook, GitHub, Google, Spotify, Twitch, Twitter, OAuth2Tokens } from 'arctic';
|
|
5
|
-
import { createJWT, validateJWT, parseJWT } from 'oslo/jwt';
|
|
6
|
-
import { betterFetch } from '@better-fetch/fetch';
|
|
7
|
-
import { TimeSpan } from 'oslo';
|
|
8
|
-
import { nanoid } from 'nanoid';
|
|
9
|
-
import { createConsola } from 'consola';
|
|
10
|
-
import { xchacha20poly1305 } from '@noble/ciphers/chacha';
|
|
11
|
-
import { utf8ToBytes, bytesToHex, hexToBytes } from '@noble/ciphers/utils';
|
|
12
|
-
import { managedNonce } from '@noble/ciphers/webcrypto';
|
|
13
|
-
import { sha256 } from '@noble/hashes/sha256';
|
|
14
|
-
import 'chalk';
|
|
15
|
-
import 'kysely';
|
|
16
|
-
import { TOTPController, createTOTPKeyURI } from 'oslo/otp';
|
|
17
|
-
import { generateRegistrationOptions, generateAuthenticationOptions, verifyRegistrationResponse, verifyAuthenticationResponse } from '@simplewebauthn/server';
|
|
18
|
-
import { startAuthentication, startRegistration, WebAuthnError } from '@simplewebauthn/browser';
|
|
19
|
-
import { atom, onMount } from 'nanostores';
|
|
20
|
-
import 'process';
|
|
21
|
-
|
|
22
1
|
var __defProp = Object.defineProperty;
|
|
23
2
|
var __export = (target, all) => {
|
|
24
3
|
for (var name in all)
|
|
25
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
5
|
};
|
|
6
|
+
|
|
7
|
+
// src/plugins/organization/organization.ts
|
|
8
|
+
import { APIError as APIError7 } from "better-call";
|
|
9
|
+
import {
|
|
10
|
+
z as z16
|
|
11
|
+
} from "zod";
|
|
12
|
+
|
|
13
|
+
// src/api/call.ts
|
|
14
|
+
import {
|
|
15
|
+
createEndpointCreator,
|
|
16
|
+
createMiddleware,
|
|
17
|
+
createMiddlewareCreator
|
|
18
|
+
} from "better-call";
|
|
27
19
|
var optionsMiddleware = createMiddleware(async () => {
|
|
28
20
|
return {};
|
|
29
21
|
});
|
|
@@ -42,27 +34,30 @@ var createAuthEndpoint = createEndpointCreator({
|
|
|
42
34
|
use: [optionsMiddleware]
|
|
43
35
|
});
|
|
44
36
|
|
|
45
|
-
// src/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
37
|
+
// src/api/routes/sign-in.ts
|
|
38
|
+
import { APIError as APIError2 } from "better-call";
|
|
39
|
+
import { generateCodeVerifier } from "oslo/oauth2";
|
|
40
|
+
import { z as z3 } from "zod";
|
|
41
|
+
|
|
42
|
+
// src/social-providers/apple.ts
|
|
43
|
+
import "arctic";
|
|
44
|
+
import { parseJWT } from "oslo/jwt";
|
|
45
|
+
import "@better-fetch/fetch";
|
|
46
|
+
|
|
47
|
+
// src/error/better-auth-error.ts
|
|
48
|
+
var BetterAuthError = class extends Error {
|
|
49
|
+
constructor(message, cause) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.name = "BetterAuthError";
|
|
52
|
+
this.message = message;
|
|
53
|
+
this.cause = cause;
|
|
54
|
+
this.stack = "";
|
|
62
55
|
}
|
|
63
|
-
return shimmedObj;
|
|
64
56
|
};
|
|
65
57
|
|
|
58
|
+
// src/social-providers/utils.ts
|
|
59
|
+
import { OAuth2Tokens } from "arctic";
|
|
60
|
+
|
|
66
61
|
// src/utils/base-url.ts
|
|
67
62
|
function checkHasPath(url) {
|
|
68
63
|
try {
|
|
@@ -83,6 +78,9 @@ function withPath(url, path = "/api/auth") {
|
|
|
83
78
|
return `${url}${path}`;
|
|
84
79
|
}
|
|
85
80
|
function getBaseURL(url, path) {
|
|
81
|
+
if (url) {
|
|
82
|
+
return withPath(url, path);
|
|
83
|
+
}
|
|
86
84
|
const env = process?.env || {};
|
|
87
85
|
const fromEnv = env.BETTER_AUTH_URL || env.NEXT_PUBLIC_BETTER_AUTH_URL || env.PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_AUTH_URL || (env.BASE_URL !== "/" ? env.BASE_URL : void 0);
|
|
88
86
|
if (fromEnv) {
|
|
@@ -93,159 +91,9 @@ function getBaseURL(url, path) {
|
|
|
93
91
|
}
|
|
94
92
|
return void 0;
|
|
95
93
|
}
|
|
96
|
-
async function setSessionCookie(ctx, sessionToken, dontRememberMe, overrides) {
|
|
97
|
-
const options = ctx.context.authCookies.sessionToken.options;
|
|
98
|
-
options.maxAge = dontRememberMe ? void 0 : options.maxAge;
|
|
99
|
-
await ctx.setSignedCookie(
|
|
100
|
-
ctx.context.authCookies.sessionToken.name,
|
|
101
|
-
sessionToken,
|
|
102
|
-
ctx.context.secret,
|
|
103
|
-
options
|
|
104
|
-
);
|
|
105
|
-
if (dontRememberMe) {
|
|
106
|
-
await ctx.setSignedCookie(
|
|
107
|
-
ctx.context.authCookies.dontRememberToken.name,
|
|
108
|
-
"true",
|
|
109
|
-
ctx.context.secret,
|
|
110
|
-
ctx.context.authCookies.dontRememberToken.options
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
function deleteSessionCookie(ctx) {
|
|
115
|
-
ctx.setCookie(ctx.context.authCookies.sessionToken.name, "", {
|
|
116
|
-
maxAge: 0
|
|
117
|
-
});
|
|
118
|
-
ctx.setCookie(ctx.context.authCookies.dontRememberToken.name, "", {
|
|
119
|
-
maxAge: 0
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
94
|
|
|
123
|
-
// src/utils
|
|
124
|
-
|
|
125
|
-
const date = /* @__PURE__ */ new Date();
|
|
126
|
-
return new Date(date.getTime() + (unit === "sec" ? span * 1e3 : span));
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// src/utils/get-request-ip.ts
|
|
130
|
-
function getIp(req) {
|
|
131
|
-
const testIP = "127.0.0.1";
|
|
132
|
-
if (process.env.NODE_ENV === "test") {
|
|
133
|
-
return testIP;
|
|
134
|
-
}
|
|
135
|
-
const headers = [
|
|
136
|
-
"x-client-ip",
|
|
137
|
-
"x-forwarded-for",
|
|
138
|
-
"cf-connecting-ip",
|
|
139
|
-
"fastly-client-ip",
|
|
140
|
-
"x-real-ip",
|
|
141
|
-
"x-cluster-client-ip",
|
|
142
|
-
"x-forwarded",
|
|
143
|
-
"forwarded-for",
|
|
144
|
-
"forwarded"
|
|
145
|
-
];
|
|
146
|
-
for (const header of headers) {
|
|
147
|
-
const value = req.headers.get(header);
|
|
148
|
-
if (typeof value === "string") {
|
|
149
|
-
const ip = value.split(",")[0].trim();
|
|
150
|
-
if (ip) return ip;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// src/utils/hide-metadata.ts
|
|
157
|
-
var HIDE_METADATA = {
|
|
158
|
-
isAction: false
|
|
159
|
-
};
|
|
160
|
-
var generateId = (size) => {
|
|
161
|
-
return nanoid(size);
|
|
162
|
-
};
|
|
163
|
-
var consola = createConsola({
|
|
164
|
-
formatOptions: {
|
|
165
|
-
date: false,
|
|
166
|
-
colors: true,
|
|
167
|
-
compact: true
|
|
168
|
-
},
|
|
169
|
-
defaults: {
|
|
170
|
-
tag: "Better Auth"
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
var createLogger = (options) => {
|
|
174
|
-
return {
|
|
175
|
-
log: (...args) => {
|
|
176
|
-
consola.log("", ...args);
|
|
177
|
-
},
|
|
178
|
-
error: (...args) => {
|
|
179
|
-
consola.error("", ...args);
|
|
180
|
-
},
|
|
181
|
-
warn: (...args) => {
|
|
182
|
-
consola.warn("", ...args);
|
|
183
|
-
},
|
|
184
|
-
info: (...args) => {
|
|
185
|
-
consola.info("", ...args);
|
|
186
|
-
},
|
|
187
|
-
debug: (...args) => {
|
|
188
|
-
consola.debug("", ...args);
|
|
189
|
-
},
|
|
190
|
-
box: (...args) => {
|
|
191
|
-
consola.box("", ...args);
|
|
192
|
-
},
|
|
193
|
-
success: (...args) => {
|
|
194
|
-
consola.success("", ...args);
|
|
195
|
-
},
|
|
196
|
-
break: (...args) => {
|
|
197
|
-
console.log("\n");
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
};
|
|
201
|
-
var logger = createLogger();
|
|
202
|
-
|
|
203
|
-
// src/utils/password.ts
|
|
204
|
-
async function validatePassword(ctx, data) {
|
|
205
|
-
const accounts = await ctx.context.internalAdapter.findAccounts(data.userId);
|
|
206
|
-
const credentialAccount = accounts?.find(
|
|
207
|
-
(account) => account.providerId === "credential"
|
|
208
|
-
);
|
|
209
|
-
const currentPassword = credentialAccount?.password;
|
|
210
|
-
if (!credentialAccount || !currentPassword) {
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
const compare = await ctx.context.password.verify(
|
|
214
|
-
currentPassword,
|
|
215
|
-
data.password
|
|
216
|
-
);
|
|
217
|
-
return compare;
|
|
218
|
-
}
|
|
219
|
-
function generateState(callbackURL, currentURL, dontRememberMe) {
|
|
220
|
-
const code = generateState$1();
|
|
221
|
-
const state = JSON.stringify({
|
|
222
|
-
code,
|
|
223
|
-
callbackURL,
|
|
224
|
-
currentURL,
|
|
225
|
-
dontRememberMe
|
|
226
|
-
});
|
|
227
|
-
return { state, code };
|
|
228
|
-
}
|
|
229
|
-
function parseState(state) {
|
|
230
|
-
const data = z.object({
|
|
231
|
-
code: z.string(),
|
|
232
|
-
callbackURL: z.string().optional(),
|
|
233
|
-
currentURL: z.string().optional(),
|
|
234
|
-
dontRememberMe: z.boolean().optional()
|
|
235
|
-
}).safeParse(JSON.parse(state));
|
|
236
|
-
return data;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// src/error/better-auth-error.ts
|
|
240
|
-
var BetterAuthError = class extends Error {
|
|
241
|
-
constructor(message, cause) {
|
|
242
|
-
super(message);
|
|
243
|
-
this.name = "BetterAuthError";
|
|
244
|
-
this.message = message;
|
|
245
|
-
this.cause = cause;
|
|
246
|
-
this.stack = "";
|
|
247
|
-
}
|
|
248
|
-
};
|
|
95
|
+
// src/social-providers/utils.ts
|
|
96
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
249
97
|
function getRedirectURI(providerId, redirectURI) {
|
|
250
98
|
return redirectURI || `${getBaseURL()}/callback/${providerId}`;
|
|
251
99
|
}
|
|
@@ -317,6 +165,9 @@ var apple = (options) => {
|
|
|
317
165
|
}
|
|
318
166
|
};
|
|
319
167
|
};
|
|
168
|
+
|
|
169
|
+
// src/social-providers/discord.ts
|
|
170
|
+
import { betterFetch as betterFetch3 } from "@better-fetch/fetch";
|
|
320
171
|
var discord = (options) => {
|
|
321
172
|
return {
|
|
322
173
|
id: "discord",
|
|
@@ -340,7 +191,7 @@ var discord = (options) => {
|
|
|
340
191
|
});
|
|
341
192
|
},
|
|
342
193
|
async getUserInfo(token) {
|
|
343
|
-
const { data: profile, error: error2 } = await
|
|
194
|
+
const { data: profile, error: error2 } = await betterFetch3(
|
|
344
195
|
"https://discord.com/api/users/@me",
|
|
345
196
|
{
|
|
346
197
|
headers: {
|
|
@@ -371,6 +222,10 @@ var discord = (options) => {
|
|
|
371
222
|
}
|
|
372
223
|
};
|
|
373
224
|
};
|
|
225
|
+
|
|
226
|
+
// src/social-providers/facebook.ts
|
|
227
|
+
import { betterFetch as betterFetch4 } from "@better-fetch/fetch";
|
|
228
|
+
import { Facebook } from "arctic";
|
|
374
229
|
var facebook = (options) => {
|
|
375
230
|
const facebookArctic = new Facebook(
|
|
376
231
|
options.clientId,
|
|
@@ -394,7 +249,7 @@ var facebook = (options) => {
|
|
|
394
249
|
});
|
|
395
250
|
},
|
|
396
251
|
async getUserInfo(token) {
|
|
397
|
-
const { data: profile, error: error2 } = await
|
|
252
|
+
const { data: profile, error: error2 } = await betterFetch4(
|
|
398
253
|
"https://graph.facebook.com/me",
|
|
399
254
|
{
|
|
400
255
|
auth: {
|
|
@@ -418,6 +273,10 @@ var facebook = (options) => {
|
|
|
418
273
|
}
|
|
419
274
|
};
|
|
420
275
|
};
|
|
276
|
+
|
|
277
|
+
// src/social-providers/github.ts
|
|
278
|
+
import { betterFetch as betterFetch5 } from "@better-fetch/fetch";
|
|
279
|
+
import { GitHub } from "arctic";
|
|
421
280
|
var github = ({
|
|
422
281
|
clientId,
|
|
423
282
|
clientSecret,
|
|
@@ -439,7 +298,7 @@ var github = ({
|
|
|
439
298
|
return await githubArctic.validateAuthorizationCode(state);
|
|
440
299
|
},
|
|
441
300
|
async getUserInfo(token) {
|
|
442
|
-
const { data: profile, error: error2 } = await
|
|
301
|
+
const { data: profile, error: error2 } = await betterFetch5(
|
|
443
302
|
"https://api.github.com/user",
|
|
444
303
|
{
|
|
445
304
|
auth: {
|
|
@@ -453,7 +312,7 @@ var github = ({
|
|
|
453
312
|
}
|
|
454
313
|
let emailVerified = false;
|
|
455
314
|
if (!profile.email) {
|
|
456
|
-
const { data, error: error3 } = await
|
|
315
|
+
const { data, error: error3 } = await betterFetch5("https://api.github.com/user/emails", {
|
|
457
316
|
auth: {
|
|
458
317
|
type: "Bearer",
|
|
459
318
|
token: token.accessToken()
|
|
@@ -479,6 +338,54 @@ var github = ({
|
|
|
479
338
|
}
|
|
480
339
|
};
|
|
481
340
|
};
|
|
341
|
+
|
|
342
|
+
// src/social-providers/google.ts
|
|
343
|
+
import { Google } from "arctic";
|
|
344
|
+
import { parseJWT as parseJWT2 } from "oslo/jwt";
|
|
345
|
+
|
|
346
|
+
// src/utils/logger.ts
|
|
347
|
+
import { createConsola } from "consola";
|
|
348
|
+
var consola = createConsola({
|
|
349
|
+
formatOptions: {
|
|
350
|
+
date: false,
|
|
351
|
+
colors: true,
|
|
352
|
+
compact: true
|
|
353
|
+
},
|
|
354
|
+
defaults: {
|
|
355
|
+
tag: "Better Auth"
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
var createLogger = (options) => {
|
|
359
|
+
return {
|
|
360
|
+
log: (...args) => {
|
|
361
|
+
!options?.disabled && consola.log("", ...args);
|
|
362
|
+
},
|
|
363
|
+
error: (...args) => {
|
|
364
|
+
!options?.disabled && consola.error("", ...args);
|
|
365
|
+
},
|
|
366
|
+
warn: (...args) => {
|
|
367
|
+
!options?.disabled && consola.warn("", ...args);
|
|
368
|
+
},
|
|
369
|
+
info: (...args) => {
|
|
370
|
+
!options?.disabled && consola.info("", ...args);
|
|
371
|
+
},
|
|
372
|
+
debug: (...args) => {
|
|
373
|
+
!options?.disabled && consola.debug("", ...args);
|
|
374
|
+
},
|
|
375
|
+
box: (...args) => {
|
|
376
|
+
!options?.disabled && consola.box("", ...args);
|
|
377
|
+
},
|
|
378
|
+
success: (...args) => {
|
|
379
|
+
!options?.disabled && consola.success("", ...args);
|
|
380
|
+
},
|
|
381
|
+
break: (...args) => {
|
|
382
|
+
!options?.disabled && console.log("\n");
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
};
|
|
386
|
+
var logger = createLogger();
|
|
387
|
+
|
|
388
|
+
// src/social-providers/google.ts
|
|
482
389
|
var google = (options) => {
|
|
483
390
|
const googleArctic = new Google(
|
|
484
391
|
options.clientId,
|
|
@@ -519,7 +426,7 @@ var google = (options) => {
|
|
|
519
426
|
if (!token.idToken) {
|
|
520
427
|
return null;
|
|
521
428
|
}
|
|
522
|
-
const user =
|
|
429
|
+
const user = parseJWT2(token.idToken())?.payload;
|
|
523
430
|
return {
|
|
524
431
|
user: {
|
|
525
432
|
id: user.sub,
|
|
@@ -533,6 +440,10 @@ var google = (options) => {
|
|
|
533
440
|
}
|
|
534
441
|
};
|
|
535
442
|
};
|
|
443
|
+
|
|
444
|
+
// src/social-providers/spotify.ts
|
|
445
|
+
import { betterFetch as betterFetch6 } from "@better-fetch/fetch";
|
|
446
|
+
import { Spotify } from "arctic";
|
|
536
447
|
var spotify = (options) => {
|
|
537
448
|
const spotifyArctic = new Spotify(
|
|
538
449
|
options.clientId,
|
|
@@ -556,7 +467,7 @@ var spotify = (options) => {
|
|
|
556
467
|
});
|
|
557
468
|
},
|
|
558
469
|
async getUserInfo(token) {
|
|
559
|
-
const { data: profile, error: error2 } = await
|
|
470
|
+
const { data: profile, error: error2 } = await betterFetch6(
|
|
560
471
|
"https://api.spotify.com/v1/me",
|
|
561
472
|
{
|
|
562
473
|
method: "GET",
|
|
@@ -581,6 +492,10 @@ var spotify = (options) => {
|
|
|
581
492
|
}
|
|
582
493
|
};
|
|
583
494
|
};
|
|
495
|
+
|
|
496
|
+
// src/social-providers/twitch.ts
|
|
497
|
+
import { betterFetch as betterFetch7 } from "@better-fetch/fetch";
|
|
498
|
+
import { Twitch } from "arctic";
|
|
584
499
|
var twitch = (options) => {
|
|
585
500
|
const twitchArctic = new Twitch(
|
|
586
501
|
options.clientId,
|
|
@@ -603,7 +518,7 @@ var twitch = (options) => {
|
|
|
603
518
|
});
|
|
604
519
|
},
|
|
605
520
|
async getUserInfo(token) {
|
|
606
|
-
const { data: profile, error: error2 } = await
|
|
521
|
+
const { data: profile, error: error2 } = await betterFetch7(
|
|
607
522
|
"https://api.twitch.tv/helix/users",
|
|
608
523
|
{
|
|
609
524
|
method: "GET",
|
|
@@ -628,6 +543,10 @@ var twitch = (options) => {
|
|
|
628
543
|
}
|
|
629
544
|
};
|
|
630
545
|
};
|
|
546
|
+
|
|
547
|
+
// src/social-providers/twitter.ts
|
|
548
|
+
import { betterFetch as betterFetch8 } from "@better-fetch/fetch";
|
|
549
|
+
import { Twitter } from "arctic";
|
|
631
550
|
var twitter = (options) => {
|
|
632
551
|
const twitterArctic = new Twitter(
|
|
633
552
|
options.clientId,
|
|
@@ -655,7 +574,7 @@ var twitter = (options) => {
|
|
|
655
574
|
});
|
|
656
575
|
},
|
|
657
576
|
async getUserInfo(token) {
|
|
658
|
-
const { data: profile, error: error2 } = await
|
|
577
|
+
const { data: profile, error: error2 } = await betterFetch8(
|
|
659
578
|
"https://api.x.com/2/users/me?user.fields=profile_image_url",
|
|
660
579
|
{
|
|
661
580
|
method: "GET",
|
|
@@ -684,6 +603,9 @@ var twitter = (options) => {
|
|
|
684
603
|
};
|
|
685
604
|
};
|
|
686
605
|
|
|
606
|
+
// src/types/provider.ts
|
|
607
|
+
import "arctic";
|
|
608
|
+
|
|
687
609
|
// src/social-providers/index.ts
|
|
688
610
|
var oAuthProviders = {
|
|
689
611
|
apple,
|
|
@@ -696,6 +618,99 @@ var oAuthProviders = {
|
|
|
696
618
|
twitter
|
|
697
619
|
};
|
|
698
620
|
var oAuthProviderList = Object.keys(oAuthProviders);
|
|
621
|
+
|
|
622
|
+
// src/utils/state.ts
|
|
623
|
+
import { generateState as generateStateOAuth } from "oslo/oauth2";
|
|
624
|
+
import { z } from "zod";
|
|
625
|
+
function generateState(callbackURL, currentURL, dontRememberMe) {
|
|
626
|
+
const code = generateStateOAuth();
|
|
627
|
+
const state = JSON.stringify({
|
|
628
|
+
code,
|
|
629
|
+
callbackURL,
|
|
630
|
+
currentURL,
|
|
631
|
+
dontRememberMe
|
|
632
|
+
});
|
|
633
|
+
return { state, code };
|
|
634
|
+
}
|
|
635
|
+
function parseState(state) {
|
|
636
|
+
const data = z.object({
|
|
637
|
+
code: z.string(),
|
|
638
|
+
callbackURL: z.string().optional(),
|
|
639
|
+
currentURL: z.string().optional(),
|
|
640
|
+
dontRememberMe: z.boolean().optional()
|
|
641
|
+
}).safeParse(JSON.parse(state));
|
|
642
|
+
return data;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// src/api/routes/session.ts
|
|
646
|
+
import { APIError } from "better-call";
|
|
647
|
+
|
|
648
|
+
// src/utils/date.ts
|
|
649
|
+
var getDate = (span, unit = "ms") => {
|
|
650
|
+
const date = /* @__PURE__ */ new Date();
|
|
651
|
+
return new Date(date.getTime() + (unit === "sec" ? span * 1e3 : span));
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
// src/utils/cookies.ts
|
|
655
|
+
import { TimeSpan } from "oslo";
|
|
656
|
+
async function setSessionCookie(ctx, sessionToken, dontRememberMe, overrides) {
|
|
657
|
+
const options = ctx.context.authCookies.sessionToken.options;
|
|
658
|
+
options.maxAge = dontRememberMe ? void 0 : options.maxAge;
|
|
659
|
+
await ctx.setSignedCookie(
|
|
660
|
+
ctx.context.authCookies.sessionToken.name,
|
|
661
|
+
sessionToken,
|
|
662
|
+
ctx.context.secret,
|
|
663
|
+
options
|
|
664
|
+
);
|
|
665
|
+
if (dontRememberMe) {
|
|
666
|
+
await ctx.setSignedCookie(
|
|
667
|
+
ctx.context.authCookies.dontRememberToken.name,
|
|
668
|
+
"true",
|
|
669
|
+
ctx.context.secret,
|
|
670
|
+
ctx.context.authCookies.dontRememberToken.options
|
|
671
|
+
);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
function deleteSessionCookie(ctx) {
|
|
675
|
+
ctx.setCookie(ctx.context.authCookies.sessionToken.name, "", {
|
|
676
|
+
maxAge: 0
|
|
677
|
+
});
|
|
678
|
+
ctx.setCookie(ctx.context.authCookies.dontRememberToken.name, "", {
|
|
679
|
+
maxAge: 0
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// src/api/routes/session.ts
|
|
684
|
+
import { z as z2 } from "zod";
|
|
685
|
+
|
|
686
|
+
// src/utils/get-request-ip.ts
|
|
687
|
+
function getIp(req) {
|
|
688
|
+
const testIP = "127.0.0.1";
|
|
689
|
+
if (process.env.NODE_ENV === "test") {
|
|
690
|
+
return testIP;
|
|
691
|
+
}
|
|
692
|
+
const headers = [
|
|
693
|
+
"x-client-ip",
|
|
694
|
+
"x-forwarded-for",
|
|
695
|
+
"cf-connecting-ip",
|
|
696
|
+
"fastly-client-ip",
|
|
697
|
+
"x-real-ip",
|
|
698
|
+
"x-cluster-client-ip",
|
|
699
|
+
"x-forwarded",
|
|
700
|
+
"forwarded-for",
|
|
701
|
+
"forwarded"
|
|
702
|
+
];
|
|
703
|
+
for (const header of headers) {
|
|
704
|
+
const value = req.headers.get(header);
|
|
705
|
+
if (typeof value === "string") {
|
|
706
|
+
const ip = value.split(",")[0].trim();
|
|
707
|
+
if (ip) return ip;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
return null;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// src/api/routes/session.ts
|
|
699
714
|
function getRequestUniqueKey(ctx, token) {
|
|
700
715
|
if (!ctx.request) {
|
|
701
716
|
return "";
|
|
@@ -794,12 +809,12 @@ var sessionMiddleware = createAuthMiddleware(async (ctx) => {
|
|
|
794
809
|
session
|
|
795
810
|
};
|
|
796
811
|
});
|
|
797
|
-
createAuthEndpoint(
|
|
812
|
+
var revokeSession = createAuthEndpoint(
|
|
798
813
|
"/user/revoke-session",
|
|
799
814
|
{
|
|
800
815
|
method: "POST",
|
|
801
|
-
body:
|
|
802
|
-
id:
|
|
816
|
+
body: z2.object({
|
|
817
|
+
id: z2.string()
|
|
803
818
|
}),
|
|
804
819
|
use: [sessionMiddleware],
|
|
805
820
|
requireHeaders: true
|
|
@@ -824,7 +839,7 @@ createAuthEndpoint(
|
|
|
824
839
|
});
|
|
825
840
|
}
|
|
826
841
|
);
|
|
827
|
-
createAuthEndpoint(
|
|
842
|
+
var revokeSessions = createAuthEndpoint(
|
|
828
843
|
"/user/revoke-sessions",
|
|
829
844
|
{
|
|
830
845
|
method: "POST",
|
|
@@ -847,31 +862,31 @@ createAuthEndpoint(
|
|
|
847
862
|
);
|
|
848
863
|
|
|
849
864
|
// src/api/routes/sign-in.ts
|
|
850
|
-
createAuthEndpoint(
|
|
865
|
+
var signInOAuth = createAuthEndpoint(
|
|
851
866
|
"/sign-in/social",
|
|
852
867
|
{
|
|
853
868
|
method: "POST",
|
|
854
869
|
requireHeaders: true,
|
|
855
|
-
query:
|
|
870
|
+
query: z3.object({
|
|
856
871
|
/**
|
|
857
872
|
* Redirect to the current URL after the
|
|
858
873
|
* user has signed in.
|
|
859
874
|
*/
|
|
860
|
-
currentURL:
|
|
875
|
+
currentURL: z3.string().optional()
|
|
861
876
|
}).optional(),
|
|
862
|
-
body:
|
|
877
|
+
body: z3.object({
|
|
863
878
|
/**
|
|
864
879
|
* Callback URL to redirect to after the user has signed in.
|
|
865
880
|
*/
|
|
866
|
-
callbackURL:
|
|
881
|
+
callbackURL: z3.string().optional(),
|
|
867
882
|
/**
|
|
868
883
|
* OAuth2 provider to use`
|
|
869
884
|
*/
|
|
870
|
-
provider:
|
|
885
|
+
provider: z3.enum(oAuthProviderList),
|
|
871
886
|
/**
|
|
872
887
|
* If this is true the session will only be valid for the current browser session
|
|
873
888
|
*/
|
|
874
|
-
dontRememberMe:
|
|
889
|
+
dontRememberMe: z3.boolean().default(false).optional()
|
|
875
890
|
})
|
|
876
891
|
},
|
|
877
892
|
async (c) => {
|
|
@@ -885,7 +900,7 @@ createAuthEndpoint(
|
|
|
885
900
|
provider: c.body.provider
|
|
886
901
|
}
|
|
887
902
|
);
|
|
888
|
-
throw new
|
|
903
|
+
throw new APIError2("NOT_FOUND", {
|
|
889
904
|
message: "Provider not found"
|
|
890
905
|
});
|
|
891
906
|
}
|
|
@@ -925,23 +940,23 @@ createAuthEndpoint(
|
|
|
925
940
|
redirect: true
|
|
926
941
|
};
|
|
927
942
|
} catch (e) {
|
|
928
|
-
throw new
|
|
943
|
+
throw new APIError2("INTERNAL_SERVER_ERROR");
|
|
929
944
|
}
|
|
930
945
|
}
|
|
931
946
|
);
|
|
932
|
-
createAuthEndpoint(
|
|
947
|
+
var signInEmail = createAuthEndpoint(
|
|
933
948
|
"/sign-in/email",
|
|
934
949
|
{
|
|
935
950
|
method: "POST",
|
|
936
|
-
body:
|
|
937
|
-
email:
|
|
938
|
-
password:
|
|
939
|
-
callbackURL:
|
|
951
|
+
body: z3.object({
|
|
952
|
+
email: z3.string().email(),
|
|
953
|
+
password: z3.string(),
|
|
954
|
+
callbackURL: z3.string().optional(),
|
|
940
955
|
/**
|
|
941
956
|
* If this is true the session will only be valid for the current browser session
|
|
942
957
|
* @default false
|
|
943
958
|
*/
|
|
944
|
-
dontRememberMe:
|
|
959
|
+
dontRememberMe: z3.boolean().default(false).optional()
|
|
945
960
|
})
|
|
946
961
|
},
|
|
947
962
|
async (ctx) => {
|
|
@@ -949,7 +964,7 @@ createAuthEndpoint(
|
|
|
949
964
|
ctx.context.logger.error(
|
|
950
965
|
"Email and password is not enabled. Make sure to enable it in the options on you `auth.ts` file. Check `https://better-auth.com/docs/authentication/email-password` for more!"
|
|
951
966
|
);
|
|
952
|
-
throw new
|
|
967
|
+
throw new APIError2("BAD_REQUEST", {
|
|
953
968
|
message: "Email and password is not enabled"
|
|
954
969
|
});
|
|
955
970
|
}
|
|
@@ -960,9 +975,9 @@ createAuthEndpoint(
|
|
|
960
975
|
);
|
|
961
976
|
}
|
|
962
977
|
const { email, password } = ctx.body;
|
|
963
|
-
const checkEmail =
|
|
978
|
+
const checkEmail = z3.string().email().safeParse(email);
|
|
964
979
|
if (!checkEmail.success) {
|
|
965
|
-
throw new
|
|
980
|
+
throw new APIError2("BAD_REQUEST", {
|
|
966
981
|
message: "Invalid email"
|
|
967
982
|
});
|
|
968
983
|
}
|
|
@@ -970,7 +985,7 @@ createAuthEndpoint(
|
|
|
970
985
|
if (!user) {
|
|
971
986
|
await ctx.context.password.hash(password);
|
|
972
987
|
ctx.context.logger.error("User not found", { email });
|
|
973
|
-
throw new
|
|
988
|
+
throw new APIError2("UNAUTHORIZED", {
|
|
974
989
|
message: "Invalid email or password"
|
|
975
990
|
});
|
|
976
991
|
}
|
|
@@ -979,14 +994,14 @@ createAuthEndpoint(
|
|
|
979
994
|
);
|
|
980
995
|
if (!credentialAccount) {
|
|
981
996
|
ctx.context.logger.error("Credential account not found", { email });
|
|
982
|
-
throw new
|
|
997
|
+
throw new APIError2("UNAUTHORIZED", {
|
|
983
998
|
message: "Invalid email or password"
|
|
984
999
|
});
|
|
985
1000
|
}
|
|
986
1001
|
const currentPassword = credentialAccount?.password;
|
|
987
1002
|
if (!currentPassword) {
|
|
988
1003
|
ctx.context.logger.error("Password not found", { email });
|
|
989
|
-
throw new
|
|
1004
|
+
throw new APIError2("UNAUTHORIZED", {
|
|
990
1005
|
message: "Unexpected error"
|
|
991
1006
|
});
|
|
992
1007
|
}
|
|
@@ -996,7 +1011,7 @@ createAuthEndpoint(
|
|
|
996
1011
|
);
|
|
997
1012
|
if (!validPassword) {
|
|
998
1013
|
ctx.context.logger.error("Invalid password");
|
|
999
|
-
throw new
|
|
1014
|
+
throw new APIError2("UNAUTHORIZED", {
|
|
1000
1015
|
message: "Invalid email or password"
|
|
1001
1016
|
});
|
|
1002
1017
|
}
|
|
@@ -1007,7 +1022,7 @@ createAuthEndpoint(
|
|
|
1007
1022
|
);
|
|
1008
1023
|
if (!session) {
|
|
1009
1024
|
ctx.context.logger.error("Failed to create session");
|
|
1010
|
-
throw new
|
|
1025
|
+
throw new APIError2("INTERNAL_SERVER_ERROR");
|
|
1011
1026
|
}
|
|
1012
1027
|
await setSessionCookie(ctx, session.id, ctx.body.dontRememberMe);
|
|
1013
1028
|
return ctx.json({
|
|
@@ -1018,46 +1033,64 @@ createAuthEndpoint(
|
|
|
1018
1033
|
});
|
|
1019
1034
|
}
|
|
1020
1035
|
);
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1036
|
+
|
|
1037
|
+
// src/api/routes/callback.ts
|
|
1038
|
+
import { APIError as APIError3 } from "better-call";
|
|
1039
|
+
import { z as z5 } from "zod";
|
|
1040
|
+
|
|
1041
|
+
// src/db/schema.ts
|
|
1042
|
+
import { z as z4 } from "zod";
|
|
1043
|
+
var accountSchema = z4.object({
|
|
1044
|
+
id: z4.string(),
|
|
1045
|
+
providerId: z4.string(),
|
|
1046
|
+
accountId: z4.string(),
|
|
1047
|
+
userId: z4.string(),
|
|
1048
|
+
accessToken: z4.string().nullable().optional(),
|
|
1049
|
+
refreshToken: z4.string().nullable().optional(),
|
|
1050
|
+
idToken: z4.string().nullable().optional(),
|
|
1029
1051
|
/**
|
|
1030
1052
|
* Access token expires at
|
|
1031
1053
|
*/
|
|
1032
|
-
expiresAt:
|
|
1054
|
+
expiresAt: z4.date().nullable().optional(),
|
|
1033
1055
|
/**
|
|
1034
1056
|
* Password is only stored in the credential provider
|
|
1035
1057
|
*/
|
|
1036
|
-
password:
|
|
1058
|
+
password: z4.string().optional().nullable()
|
|
1037
1059
|
});
|
|
1038
|
-
var userSchema =
|
|
1039
|
-
id:
|
|
1040
|
-
email:
|
|
1041
|
-
emailVerified:
|
|
1042
|
-
name:
|
|
1043
|
-
image:
|
|
1044
|
-
createdAt:
|
|
1045
|
-
updatedAt:
|
|
1060
|
+
var userSchema = z4.object({
|
|
1061
|
+
id: z4.string(),
|
|
1062
|
+
email: z4.string().transform((val) => val.toLowerCase()),
|
|
1063
|
+
emailVerified: z4.boolean().default(false),
|
|
1064
|
+
name: z4.string(),
|
|
1065
|
+
image: z4.string().optional(),
|
|
1066
|
+
createdAt: z4.date().default(/* @__PURE__ */ new Date()),
|
|
1067
|
+
updatedAt: z4.date().default(/* @__PURE__ */ new Date())
|
|
1046
1068
|
});
|
|
1047
|
-
|
|
1048
|
-
id:
|
|
1049
|
-
userId:
|
|
1050
|
-
expiresAt:
|
|
1051
|
-
ipAddress:
|
|
1052
|
-
userAgent:
|
|
1069
|
+
var sessionSchema = z4.object({
|
|
1070
|
+
id: z4.string(),
|
|
1071
|
+
userId: z4.string(),
|
|
1072
|
+
expiresAt: z4.date(),
|
|
1073
|
+
ipAddress: z4.string().optional(),
|
|
1074
|
+
userAgent: z4.string().optional()
|
|
1053
1075
|
});
|
|
1054
|
-
|
|
1055
|
-
id:
|
|
1056
|
-
value:
|
|
1057
|
-
expiresAt:
|
|
1058
|
-
identifier:
|
|
1076
|
+
var verificationSchema = z4.object({
|
|
1077
|
+
id: z4.string(),
|
|
1078
|
+
value: z4.string(),
|
|
1079
|
+
expiresAt: z4.date(),
|
|
1080
|
+
identifier: z4.string()
|
|
1059
1081
|
});
|
|
1060
1082
|
|
|
1083
|
+
// src/utils/id.ts
|
|
1084
|
+
import { nanoid } from "nanoid";
|
|
1085
|
+
var generateId = (size) => {
|
|
1086
|
+
return nanoid(size);
|
|
1087
|
+
};
|
|
1088
|
+
|
|
1089
|
+
// src/utils/hide-metadata.ts
|
|
1090
|
+
var HIDE_METADATA = {
|
|
1091
|
+
isAction: false
|
|
1092
|
+
};
|
|
1093
|
+
|
|
1061
1094
|
// src/utils/getAccount.ts
|
|
1062
1095
|
function getAccountTokens(tokens) {
|
|
1063
1096
|
const accessToken = tokens.accessToken();
|
|
@@ -1075,14 +1108,14 @@ function getAccountTokens(tokens) {
|
|
|
1075
1108
|
}
|
|
1076
1109
|
|
|
1077
1110
|
// src/api/routes/callback.ts
|
|
1078
|
-
createAuthEndpoint(
|
|
1111
|
+
var callbackOAuth = createAuthEndpoint(
|
|
1079
1112
|
"/callback/:id",
|
|
1080
1113
|
{
|
|
1081
1114
|
method: "GET",
|
|
1082
|
-
query:
|
|
1083
|
-
state:
|
|
1084
|
-
code:
|
|
1085
|
-
error:
|
|
1115
|
+
query: z5.object({
|
|
1116
|
+
state: z5.string(),
|
|
1117
|
+
code: z5.string().optional(),
|
|
1118
|
+
error: z5.string().optional()
|
|
1086
1119
|
}),
|
|
1087
1120
|
metadata: HIDE_METADATA
|
|
1088
1121
|
},
|
|
@@ -1210,7 +1243,7 @@ createAuthEndpoint(
|
|
|
1210
1243
|
}
|
|
1211
1244
|
}
|
|
1212
1245
|
if (!userId && !id)
|
|
1213
|
-
throw new
|
|
1246
|
+
throw new APIError3("INTERNAL_SERVER_ERROR", {
|
|
1214
1247
|
message: "Unable to create user"
|
|
1215
1248
|
});
|
|
1216
1249
|
try {
|
|
@@ -1240,13 +1273,16 @@ createAuthEndpoint(
|
|
|
1240
1273
|
throw c.redirect(callbackURL);
|
|
1241
1274
|
}
|
|
1242
1275
|
);
|
|
1243
|
-
|
|
1276
|
+
|
|
1277
|
+
// src/api/routes/sign-out.ts
|
|
1278
|
+
import { z as z6 } from "zod";
|
|
1279
|
+
var signOut = createAuthEndpoint(
|
|
1244
1280
|
"/sign-out",
|
|
1245
1281
|
{
|
|
1246
1282
|
method: "POST",
|
|
1247
|
-
body:
|
|
1248
|
-
|
|
1249
|
-
callbackURL:
|
|
1283
|
+
body: z6.optional(
|
|
1284
|
+
z6.object({
|
|
1285
|
+
callbackURL: z6.string().optional()
|
|
1250
1286
|
})
|
|
1251
1287
|
)
|
|
1252
1288
|
},
|
|
@@ -1268,22 +1304,28 @@ createAuthEndpoint(
|
|
|
1268
1304
|
});
|
|
1269
1305
|
}
|
|
1270
1306
|
);
|
|
1271
|
-
|
|
1307
|
+
|
|
1308
|
+
// src/api/routes/forget-password.ts
|
|
1309
|
+
import { TimeSpan as TimeSpan2 } from "oslo";
|
|
1310
|
+
import { createJWT, parseJWT as parseJWT3 } from "oslo/jwt";
|
|
1311
|
+
import { validateJWT } from "oslo/jwt";
|
|
1312
|
+
import { z as z7 } from "zod";
|
|
1313
|
+
var forgetPassword = createAuthEndpoint(
|
|
1272
1314
|
"/forget-password",
|
|
1273
1315
|
{
|
|
1274
1316
|
method: "POST",
|
|
1275
|
-
body:
|
|
1317
|
+
body: z7.object({
|
|
1276
1318
|
/**
|
|
1277
1319
|
* The email address of the user to send a password reset email to.
|
|
1278
1320
|
*/
|
|
1279
|
-
email:
|
|
1321
|
+
email: z7.string().email(),
|
|
1280
1322
|
/**
|
|
1281
1323
|
* The URL to redirect the user to reset their password.
|
|
1282
1324
|
* If the token isn't valid or expired, it'll be redirected with a query parameter `?
|
|
1283
1325
|
* error=INVALID_TOKEN`. If the token is valid, it'll be redirected with a query parameter `?
|
|
1284
1326
|
* token=VALID_TOKEN
|
|
1285
1327
|
*/
|
|
1286
|
-
redirectTo:
|
|
1328
|
+
redirectTo: z7.string()
|
|
1287
1329
|
})
|
|
1288
1330
|
},
|
|
1289
1331
|
async (ctx) => {
|
|
@@ -1321,7 +1363,7 @@ createAuthEndpoint(
|
|
|
1321
1363
|
redirectTo: ctx.body.redirectTo
|
|
1322
1364
|
},
|
|
1323
1365
|
{
|
|
1324
|
-
expiresIn: new
|
|
1366
|
+
expiresIn: new TimeSpan2(1, "h"),
|
|
1325
1367
|
issuer: "better-auth",
|
|
1326
1368
|
subject: "forget-password",
|
|
1327
1369
|
audiences: [user.user.email],
|
|
@@ -1338,7 +1380,7 @@ createAuthEndpoint(
|
|
|
1338
1380
|
});
|
|
1339
1381
|
}
|
|
1340
1382
|
);
|
|
1341
|
-
createAuthEndpoint(
|
|
1383
|
+
var forgetPasswordCallback = createAuthEndpoint(
|
|
1342
1384
|
"/reset-password/:token",
|
|
1343
1385
|
{
|
|
1344
1386
|
method: "GET"
|
|
@@ -1346,9 +1388,9 @@ createAuthEndpoint(
|
|
|
1346
1388
|
async (ctx) => {
|
|
1347
1389
|
const { token } = ctx.params;
|
|
1348
1390
|
let decodedToken;
|
|
1349
|
-
const schema =
|
|
1350
|
-
email:
|
|
1351
|
-
redirectTo:
|
|
1391
|
+
const schema = z7.object({
|
|
1392
|
+
email: z7.string(),
|
|
1393
|
+
redirectTo: z7.string()
|
|
1352
1394
|
});
|
|
1353
1395
|
try {
|
|
1354
1396
|
decodedToken = await validateJWT(
|
|
@@ -1360,7 +1402,7 @@ createAuthEndpoint(
|
|
|
1360
1402
|
throw Error("Token expired");
|
|
1361
1403
|
}
|
|
1362
1404
|
} catch (e) {
|
|
1363
|
-
const decoded =
|
|
1405
|
+
const decoded = parseJWT3(token);
|
|
1364
1406
|
const jwt = schema.safeParse(decoded?.payload);
|
|
1365
1407
|
if (jwt.success) {
|
|
1366
1408
|
throw ctx.redirect(`${jwt.data?.redirectTo}?error=invalid_token`);
|
|
@@ -1372,16 +1414,16 @@ createAuthEndpoint(
|
|
|
1372
1414
|
throw ctx.redirect(`${redirectTo}?token=${token}`);
|
|
1373
1415
|
}
|
|
1374
1416
|
);
|
|
1375
|
-
createAuthEndpoint(
|
|
1417
|
+
var resetPassword = createAuthEndpoint(
|
|
1376
1418
|
"/reset-password",
|
|
1377
1419
|
{
|
|
1378
1420
|
method: "POST",
|
|
1379
|
-
query:
|
|
1380
|
-
currentURL:
|
|
1421
|
+
query: z7.object({
|
|
1422
|
+
currentURL: z7.string()
|
|
1381
1423
|
}).optional(),
|
|
1382
|
-
body:
|
|
1383
|
-
newPassword:
|
|
1384
|
-
callbackURL:
|
|
1424
|
+
body: z7.object({
|
|
1425
|
+
newPassword: z7.string(),
|
|
1426
|
+
callbackURL: z7.string().optional()
|
|
1385
1427
|
})
|
|
1386
1428
|
},
|
|
1387
1429
|
async (ctx) => {
|
|
@@ -1408,7 +1450,7 @@ createAuthEndpoint(
|
|
|
1408
1450
|
Buffer.from(ctx.context.secret),
|
|
1409
1451
|
token
|
|
1410
1452
|
);
|
|
1411
|
-
const email =
|
|
1453
|
+
const email = z7.string().email().parse(jwt.payload.email);
|
|
1412
1454
|
const user = await ctx.context.internalAdapter.findUserByEmail(email);
|
|
1413
1455
|
if (!user) {
|
|
1414
1456
|
return ctx.json(
|
|
@@ -1488,15 +1530,20 @@ createAuthEndpoint(
|
|
|
1488
1530
|
}
|
|
1489
1531
|
}
|
|
1490
1532
|
);
|
|
1533
|
+
|
|
1534
|
+
// src/api/routes/verify-email.ts
|
|
1535
|
+
import { TimeSpan as TimeSpan3 } from "oslo";
|
|
1536
|
+
import { createJWT as createJWT2, validateJWT as validateJWT2 } from "oslo/jwt";
|
|
1537
|
+
import { z as z8 } from "zod";
|
|
1491
1538
|
async function createEmailVerificationToken(secret, email) {
|
|
1492
|
-
const token = await
|
|
1539
|
+
const token = await createJWT2(
|
|
1493
1540
|
"HS256",
|
|
1494
1541
|
Buffer.from(secret),
|
|
1495
1542
|
{
|
|
1496
1543
|
email: email.toLowerCase()
|
|
1497
1544
|
},
|
|
1498
1545
|
{
|
|
1499
|
-
expiresIn: new
|
|
1546
|
+
expiresIn: new TimeSpan3(1, "h"),
|
|
1500
1547
|
issuer: "better-auth",
|
|
1501
1548
|
subject: "verify-email",
|
|
1502
1549
|
audiences: [email],
|
|
@@ -1505,16 +1552,16 @@ async function createEmailVerificationToken(secret, email) {
|
|
|
1505
1552
|
);
|
|
1506
1553
|
return token;
|
|
1507
1554
|
}
|
|
1508
|
-
createAuthEndpoint(
|
|
1555
|
+
var sendVerificationEmail = createAuthEndpoint(
|
|
1509
1556
|
"/send-verification-email",
|
|
1510
1557
|
{
|
|
1511
1558
|
method: "POST",
|
|
1512
|
-
query:
|
|
1513
|
-
currentURL:
|
|
1559
|
+
query: z8.object({
|
|
1560
|
+
currentURL: z8.string().optional()
|
|
1514
1561
|
}).optional(),
|
|
1515
|
-
body:
|
|
1516
|
-
email:
|
|
1517
|
-
callbackURL:
|
|
1562
|
+
body: z8.object({
|
|
1563
|
+
email: z8.string().email(),
|
|
1564
|
+
callbackURL: z8.string().optional()
|
|
1518
1565
|
})
|
|
1519
1566
|
},
|
|
1520
1567
|
async (ctx) => {
|
|
@@ -1543,20 +1590,20 @@ createAuthEndpoint(
|
|
|
1543
1590
|
});
|
|
1544
1591
|
}
|
|
1545
1592
|
);
|
|
1546
|
-
createAuthEndpoint(
|
|
1593
|
+
var verifyEmail = createAuthEndpoint(
|
|
1547
1594
|
"/verify-email",
|
|
1548
1595
|
{
|
|
1549
1596
|
method: "GET",
|
|
1550
|
-
query:
|
|
1551
|
-
token:
|
|
1552
|
-
callbackURL:
|
|
1597
|
+
query: z8.object({
|
|
1598
|
+
token: z8.string(),
|
|
1599
|
+
callbackURL: z8.string().optional()
|
|
1553
1600
|
})
|
|
1554
1601
|
},
|
|
1555
1602
|
async (ctx) => {
|
|
1556
1603
|
const { token } = ctx.query;
|
|
1557
1604
|
let jwt;
|
|
1558
1605
|
try {
|
|
1559
|
-
jwt = await
|
|
1606
|
+
jwt = await validateJWT2("HS256", Buffer.from(ctx.context.secret), token);
|
|
1560
1607
|
} catch (e) {
|
|
1561
1608
|
ctx.context.logger.error("Failed to verify email", e);
|
|
1562
1609
|
return ctx.json(null, {
|
|
@@ -1567,8 +1614,8 @@ createAuthEndpoint(
|
|
|
1567
1614
|
}
|
|
1568
1615
|
});
|
|
1569
1616
|
}
|
|
1570
|
-
const schema =
|
|
1571
|
-
email:
|
|
1617
|
+
const schema = z8.object({
|
|
1618
|
+
email: z8.string().email()
|
|
1572
1619
|
});
|
|
1573
1620
|
const parsed = schema.parse(jwt.payload);
|
|
1574
1621
|
const user = await ctx.context.internalAdapter.findUserByEmail(
|
|
@@ -1600,6 +1647,9 @@ createAuthEndpoint(
|
|
|
1600
1647
|
}
|
|
1601
1648
|
);
|
|
1602
1649
|
|
|
1650
|
+
// src/api/routes/update-user.ts
|
|
1651
|
+
import { z as z9 } from "zod";
|
|
1652
|
+
|
|
1603
1653
|
// src/crypto/random.ts
|
|
1604
1654
|
function byteToBinary(byte) {
|
|
1605
1655
|
return byte.toString(2).padStart(8, "0");
|
|
@@ -1658,13 +1708,13 @@ function alphabet(...patterns) {
|
|
|
1658
1708
|
}
|
|
1659
1709
|
|
|
1660
1710
|
// src/api/routes/update-user.ts
|
|
1661
|
-
createAuthEndpoint(
|
|
1711
|
+
var updateUser = createAuthEndpoint(
|
|
1662
1712
|
"/user/update",
|
|
1663
1713
|
{
|
|
1664
1714
|
method: "POST",
|
|
1665
|
-
body:
|
|
1666
|
-
name:
|
|
1667
|
-
image:
|
|
1715
|
+
body: z9.object({
|
|
1716
|
+
name: z9.string().optional(),
|
|
1717
|
+
image: z9.string().optional()
|
|
1668
1718
|
}),
|
|
1669
1719
|
use: [sessionMiddleware]
|
|
1670
1720
|
},
|
|
@@ -1684,24 +1734,24 @@ createAuthEndpoint(
|
|
|
1684
1734
|
return ctx.json(user);
|
|
1685
1735
|
}
|
|
1686
1736
|
);
|
|
1687
|
-
createAuthEndpoint(
|
|
1737
|
+
var changePassword = createAuthEndpoint(
|
|
1688
1738
|
"/user/change-password",
|
|
1689
1739
|
{
|
|
1690
1740
|
method: "POST",
|
|
1691
|
-
body:
|
|
1741
|
+
body: z9.object({
|
|
1692
1742
|
/**
|
|
1693
1743
|
* The new password to set
|
|
1694
1744
|
*/
|
|
1695
|
-
newPassword:
|
|
1745
|
+
newPassword: z9.string(),
|
|
1696
1746
|
/**
|
|
1697
1747
|
* The current password of the user
|
|
1698
1748
|
*/
|
|
1699
|
-
currentPassword:
|
|
1749
|
+
currentPassword: z9.string(),
|
|
1700
1750
|
/**
|
|
1701
1751
|
* revoke all sessions that are not the
|
|
1702
1752
|
* current one logged in by the user
|
|
1703
1753
|
*/
|
|
1704
|
-
revokeOtherSessions:
|
|
1754
|
+
revokeOtherSessions: z9.boolean().optional()
|
|
1705
1755
|
}),
|
|
1706
1756
|
use: [sessionMiddleware]
|
|
1707
1757
|
},
|
|
@@ -1767,15 +1817,15 @@ createAuthEndpoint(
|
|
|
1767
1817
|
return ctx.json(session.user);
|
|
1768
1818
|
}
|
|
1769
1819
|
);
|
|
1770
|
-
createAuthEndpoint(
|
|
1820
|
+
var setPassword = createAuthEndpoint(
|
|
1771
1821
|
"/user/set-password",
|
|
1772
1822
|
{
|
|
1773
1823
|
method: "POST",
|
|
1774
|
-
body:
|
|
1824
|
+
body: z9.object({
|
|
1775
1825
|
/**
|
|
1776
1826
|
* The new password to set
|
|
1777
1827
|
*/
|
|
1778
|
-
newPassword:
|
|
1828
|
+
newPassword: z9.string()
|
|
1779
1829
|
}),
|
|
1780
1830
|
use: [sessionMiddleware]
|
|
1781
1831
|
},
|
|
@@ -1821,12 +1871,12 @@ createAuthEndpoint(
|
|
|
1821
1871
|
});
|
|
1822
1872
|
}
|
|
1823
1873
|
);
|
|
1824
|
-
createAuthEndpoint(
|
|
1874
|
+
var deleteUser = createAuthEndpoint(
|
|
1825
1875
|
"/user/delete",
|
|
1826
1876
|
{
|
|
1827
1877
|
method: "POST",
|
|
1828
|
-
body:
|
|
1829
|
-
password:
|
|
1878
|
+
body: z9.object({
|
|
1879
|
+
password: z9.string()
|
|
1830
1880
|
}),
|
|
1831
1881
|
use: [sessionMiddleware]
|
|
1832
1882
|
},
|
|
@@ -1860,6 +1910,12 @@ createAuthEndpoint(
|
|
|
1860
1910
|
return ctx.json(null);
|
|
1861
1911
|
}
|
|
1862
1912
|
);
|
|
1913
|
+
|
|
1914
|
+
// src/crypto/index.ts
|
|
1915
|
+
import { xchacha20poly1305 } from "@noble/ciphers/chacha";
|
|
1916
|
+
import { bytesToHex, hexToBytes, utf8ToBytes } from "@noble/ciphers/utils";
|
|
1917
|
+
import { managedNonce } from "@noble/ciphers/webcrypto";
|
|
1918
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
1863
1919
|
async function hs256(secretKey, message) {
|
|
1864
1920
|
const enc = new TextEncoder();
|
|
1865
1921
|
const algorithm = { name: "HMAC", hash: "SHA-256" };
|
|
@@ -1891,7 +1947,7 @@ var symmetricDecrypt = ({ key, data }) => {
|
|
|
1891
1947
|
};
|
|
1892
1948
|
|
|
1893
1949
|
// src/api/routes/csrf.ts
|
|
1894
|
-
createAuthEndpoint(
|
|
1950
|
+
var getCSRFToken = createAuthEndpoint(
|
|
1895
1951
|
"/csrf",
|
|
1896
1952
|
{
|
|
1897
1953
|
method: "GET",
|
|
@@ -2004,7 +2060,7 @@ var html = (errorCode = "Unknown") => `<!DOCTYPE html>
|
|
|
2004
2060
|
</div>
|
|
2005
2061
|
</body>
|
|
2006
2062
|
</html>`;
|
|
2007
|
-
createAuthEndpoint(
|
|
2063
|
+
var error = createAuthEndpoint(
|
|
2008
2064
|
"/error",
|
|
2009
2065
|
{
|
|
2010
2066
|
method: "GET",
|
|
@@ -2021,7 +2077,7 @@ createAuthEndpoint(
|
|
|
2021
2077
|
);
|
|
2022
2078
|
|
|
2023
2079
|
// src/api/routes/ok.ts
|
|
2024
|
-
createAuthEndpoint(
|
|
2080
|
+
var ok = createAuthEndpoint(
|
|
2025
2081
|
"/ok",
|
|
2026
2082
|
{
|
|
2027
2083
|
method: "GET",
|
|
@@ -2033,19 +2089,22 @@ createAuthEndpoint(
|
|
|
2033
2089
|
});
|
|
2034
2090
|
}
|
|
2035
2091
|
);
|
|
2092
|
+
|
|
2093
|
+
// src/api/routes/sign-up.ts
|
|
2094
|
+
import { z as z10 } from "zod";
|
|
2036
2095
|
var signUpEmail = createAuthEndpoint(
|
|
2037
2096
|
"/sign-up/email",
|
|
2038
2097
|
{
|
|
2039
2098
|
method: "POST",
|
|
2040
|
-
query:
|
|
2041
|
-
currentURL:
|
|
2099
|
+
query: z10.object({
|
|
2100
|
+
currentURL: z10.string().optional()
|
|
2042
2101
|
}).optional(),
|
|
2043
|
-
body:
|
|
2044
|
-
name:
|
|
2045
|
-
email:
|
|
2046
|
-
password:
|
|
2047
|
-
image:
|
|
2048
|
-
callbackURL:
|
|
2102
|
+
body: z10.object({
|
|
2103
|
+
name: z10.string(),
|
|
2104
|
+
email: z10.string(),
|
|
2105
|
+
password: z10.string(),
|
|
2106
|
+
image: z10.string().optional(),
|
|
2107
|
+
callbackURL: z10.string().optional()
|
|
2049
2108
|
})
|
|
2050
2109
|
},
|
|
2051
2110
|
async (ctx) => {
|
|
@@ -2058,7 +2117,7 @@ var signUpEmail = createAuthEndpoint(
|
|
|
2058
2117
|
});
|
|
2059
2118
|
}
|
|
2060
2119
|
const { name, email, password, image } = ctx.body;
|
|
2061
|
-
const isValidEmail =
|
|
2120
|
+
const isValidEmail = z10.string().email().safeParse(email);
|
|
2062
2121
|
if (!isValidEmail.success) {
|
|
2063
2122
|
return ctx.json(null, {
|
|
2064
2123
|
status: 400,
|
|
@@ -2160,6 +2219,27 @@ var signUpEmail = createAuthEndpoint(
|
|
|
2160
2219
|
}
|
|
2161
2220
|
);
|
|
2162
2221
|
|
|
2222
|
+
// src/utils/shim.ts
|
|
2223
|
+
var shimContext = (originalObject, newContext) => {
|
|
2224
|
+
const shimmedObj = {};
|
|
2225
|
+
for (const [key, value] of Object.entries(originalObject)) {
|
|
2226
|
+
shimmedObj[key] = (ctx) => {
|
|
2227
|
+
return value({
|
|
2228
|
+
...ctx,
|
|
2229
|
+
context: {
|
|
2230
|
+
...newContext,
|
|
2231
|
+
...ctx.context
|
|
2232
|
+
}
|
|
2233
|
+
});
|
|
2234
|
+
};
|
|
2235
|
+
shimmedObj[key].path = value.path;
|
|
2236
|
+
shimmedObj[key].method = value.method;
|
|
2237
|
+
shimmedObj[key].options = value.options;
|
|
2238
|
+
shimmedObj[key].headers = value.headers;
|
|
2239
|
+
}
|
|
2240
|
+
return shimmedObj;
|
|
2241
|
+
};
|
|
2242
|
+
|
|
2163
2243
|
// src/plugins/organization/access/index.ts
|
|
2164
2244
|
var access_exports = {};
|
|
2165
2245
|
__export(access_exports, {
|
|
@@ -2806,10 +2886,23 @@ var getOrgAdapter = (adapter, options) => {
|
|
|
2806
2886
|
}
|
|
2807
2887
|
};
|
|
2808
2888
|
};
|
|
2809
|
-
|
|
2889
|
+
|
|
2890
|
+
// src/plugins/organization/call.ts
|
|
2891
|
+
import "better-call";
|
|
2892
|
+
|
|
2893
|
+
// src/api/index.ts
|
|
2894
|
+
import {
|
|
2895
|
+
APIError as APIError5,
|
|
2896
|
+
createRouter
|
|
2897
|
+
} from "better-call";
|
|
2898
|
+
|
|
2899
|
+
// src/api/middlewares/csrf.ts
|
|
2900
|
+
import { APIError as APIError4 } from "better-call";
|
|
2901
|
+
import { z as z11 } from "zod";
|
|
2902
|
+
var csrfMiddleware = createAuthMiddleware(
|
|
2810
2903
|
{
|
|
2811
|
-
body:
|
|
2812
|
-
csrfToken:
|
|
2904
|
+
body: z11.object({
|
|
2905
|
+
csrfToken: z11.string().optional()
|
|
2813
2906
|
}).optional()
|
|
2814
2907
|
},
|
|
2815
2908
|
async (ctx) => {
|
|
@@ -2830,7 +2923,7 @@ createAuthMiddleware(
|
|
|
2830
2923
|
ctx.setCookie(ctx.context.authCookies.csrfToken.name, "", {
|
|
2831
2924
|
maxAge: 0
|
|
2832
2925
|
});
|
|
2833
|
-
throw new
|
|
2926
|
+
throw new APIError4("UNAUTHORIZED", {
|
|
2834
2927
|
message: "Invalid CSRF Token"
|
|
2835
2928
|
});
|
|
2836
2929
|
}
|
|
@@ -2839,13 +2932,16 @@ createAuthMiddleware(
|
|
|
2839
2932
|
ctx.setCookie(ctx.context.authCookies.csrfToken.name, "", {
|
|
2840
2933
|
maxAge: 0
|
|
2841
2934
|
});
|
|
2842
|
-
throw new
|
|
2935
|
+
throw new APIError4("UNAUTHORIZED", {
|
|
2843
2936
|
message: "Invalid CSRF Token"
|
|
2844
2937
|
});
|
|
2845
2938
|
}
|
|
2846
2939
|
}
|
|
2847
2940
|
);
|
|
2848
2941
|
|
|
2942
|
+
// src/api/index.ts
|
|
2943
|
+
import chalk from "chalk";
|
|
2944
|
+
|
|
2849
2945
|
// src/plugins/organization/call.ts
|
|
2850
2946
|
var orgMiddleware = createAuthMiddleware(async (ctx) => {
|
|
2851
2947
|
return {};
|
|
@@ -2861,35 +2957,41 @@ var orgSessionMiddleware = createAuthMiddleware(
|
|
|
2861
2957
|
};
|
|
2862
2958
|
}
|
|
2863
2959
|
);
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
z
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2960
|
+
|
|
2961
|
+
// src/plugins/organization/routes/crud-invites.ts
|
|
2962
|
+
import { z as z13 } from "zod";
|
|
2963
|
+
|
|
2964
|
+
// src/plugins/organization/schema.ts
|
|
2965
|
+
import { z as z12 } from "zod";
|
|
2966
|
+
var role = z12.enum(["admin", "member", "owner"]);
|
|
2967
|
+
var invitationStatus = z12.enum(["pending", "accepted", "rejected", "canceled"]).default("pending");
|
|
2968
|
+
var organizationSchema = z12.object({
|
|
2969
|
+
id: z12.string(),
|
|
2970
|
+
name: z12.string(),
|
|
2971
|
+
slug: z12.string(),
|
|
2972
|
+
logo: z12.string().optional(),
|
|
2973
|
+
metadata: z12.record(z12.string()).or(z12.string().transform((v) => JSON.parse(v))).optional(),
|
|
2974
|
+
createdAt: z12.date()
|
|
2873
2975
|
});
|
|
2874
|
-
|
|
2875
|
-
id:
|
|
2876
|
-
email:
|
|
2877
|
-
organizationId:
|
|
2878
|
-
userId:
|
|
2976
|
+
var memberSchema = z12.object({
|
|
2977
|
+
id: z12.string(),
|
|
2978
|
+
email: z12.string(),
|
|
2979
|
+
organizationId: z12.string(),
|
|
2980
|
+
userId: z12.string(),
|
|
2879
2981
|
role,
|
|
2880
|
-
createdAt:
|
|
2982
|
+
createdAt: z12.date()
|
|
2881
2983
|
});
|
|
2882
|
-
|
|
2883
|
-
id:
|
|
2884
|
-
organizationId:
|
|
2885
|
-
email:
|
|
2984
|
+
var invitationSchema = z12.object({
|
|
2985
|
+
id: z12.string(),
|
|
2986
|
+
organizationId: z12.string(),
|
|
2987
|
+
email: z12.string(),
|
|
2886
2988
|
role,
|
|
2887
2989
|
status: invitationStatus,
|
|
2888
2990
|
/**
|
|
2889
2991
|
* The id of the user who invited the user.
|
|
2890
2992
|
*/
|
|
2891
|
-
inviterId:
|
|
2892
|
-
expiresAt:
|
|
2993
|
+
inviterId: z12.string(),
|
|
2994
|
+
expiresAt: z12.date()
|
|
2893
2995
|
});
|
|
2894
2996
|
|
|
2895
2997
|
// src/plugins/organization/routes/crud-invites.ts
|
|
@@ -2898,11 +3000,11 @@ var createInvitation = createAuthEndpoint(
|
|
|
2898
3000
|
{
|
|
2899
3001
|
method: "POST",
|
|
2900
3002
|
use: [orgMiddleware, orgSessionMiddleware],
|
|
2901
|
-
body:
|
|
2902
|
-
email:
|
|
3003
|
+
body: z13.object({
|
|
3004
|
+
email: z13.string(),
|
|
2903
3005
|
role,
|
|
2904
|
-
organizationId:
|
|
2905
|
-
resend:
|
|
3006
|
+
organizationId: z13.string().optional(),
|
|
3007
|
+
resend: z13.boolean().optional()
|
|
2906
3008
|
})
|
|
2907
3009
|
},
|
|
2908
3010
|
async (ctx) => {
|
|
@@ -3021,8 +3123,8 @@ var acceptInvitation = createAuthEndpoint(
|
|
|
3021
3123
|
"/organization/accept-invitation",
|
|
3022
3124
|
{
|
|
3023
3125
|
method: "POST",
|
|
3024
|
-
body:
|
|
3025
|
-
invitationId:
|
|
3126
|
+
body: z13.object({
|
|
3127
|
+
invitationId: z13.string()
|
|
3026
3128
|
}),
|
|
3027
3129
|
use: [orgMiddleware, orgSessionMiddleware]
|
|
3028
3130
|
},
|
|
@@ -3080,8 +3182,8 @@ var rejectInvitation = createAuthEndpoint(
|
|
|
3080
3182
|
"/organization/reject-invitation",
|
|
3081
3183
|
{
|
|
3082
3184
|
method: "POST",
|
|
3083
|
-
body:
|
|
3084
|
-
invitationId:
|
|
3185
|
+
body: z13.object({
|
|
3186
|
+
invitationId: z13.string()
|
|
3085
3187
|
}),
|
|
3086
3188
|
use: [orgMiddleware, orgSessionMiddleware]
|
|
3087
3189
|
},
|
|
@@ -3119,8 +3221,8 @@ var cancelInvitation = createAuthEndpoint(
|
|
|
3119
3221
|
"/organization/cancel-invitation",
|
|
3120
3222
|
{
|
|
3121
3223
|
method: "POST",
|
|
3122
|
-
body:
|
|
3123
|
-
invitationId:
|
|
3224
|
+
body: z13.object({
|
|
3225
|
+
invitationId: z13.string()
|
|
3124
3226
|
}),
|
|
3125
3227
|
use: [orgMiddleware, orgSessionMiddleware]
|
|
3126
3228
|
},
|
|
@@ -3172,8 +3274,8 @@ var getInvitation = createAuthEndpoint(
|
|
|
3172
3274
|
method: "GET",
|
|
3173
3275
|
use: [orgMiddleware],
|
|
3174
3276
|
requireHeaders: true,
|
|
3175
|
-
query:
|
|
3176
|
-
id:
|
|
3277
|
+
query: z13.object({
|
|
3278
|
+
id: z13.string()
|
|
3177
3279
|
})
|
|
3178
3280
|
},
|
|
3179
3281
|
async (ctx) => {
|
|
@@ -3235,16 +3337,19 @@ var getInvitation = createAuthEndpoint(
|
|
|
3235
3337
|
});
|
|
3236
3338
|
}
|
|
3237
3339
|
);
|
|
3340
|
+
|
|
3341
|
+
// src/plugins/organization/routes/crud-members.ts
|
|
3342
|
+
import { z as z14 } from "zod";
|
|
3238
3343
|
var removeMember = createAuthEndpoint(
|
|
3239
3344
|
"/organization/remove-member",
|
|
3240
3345
|
{
|
|
3241
3346
|
method: "POST",
|
|
3242
|
-
body:
|
|
3243
|
-
memberIdOrEmail:
|
|
3347
|
+
body: z14.object({
|
|
3348
|
+
memberIdOrEmail: z14.string(),
|
|
3244
3349
|
/**
|
|
3245
3350
|
* If not provided, the active organization will be used
|
|
3246
3351
|
*/
|
|
3247
|
-
organizationId:
|
|
3352
|
+
organizationId: z14.string().optional()
|
|
3248
3353
|
}),
|
|
3249
3354
|
use: [orgMiddleware, orgSessionMiddleware]
|
|
3250
3355
|
},
|
|
@@ -3332,13 +3437,13 @@ var updateMemberRole = createAuthEndpoint(
|
|
|
3332
3437
|
"/organization/update-member-role",
|
|
3333
3438
|
{
|
|
3334
3439
|
method: "POST",
|
|
3335
|
-
body:
|
|
3336
|
-
role:
|
|
3337
|
-
memberId:
|
|
3440
|
+
body: z14.object({
|
|
3441
|
+
role: z14.enum(["admin", "member", "owner"]),
|
|
3442
|
+
memberId: z14.string(),
|
|
3338
3443
|
/**
|
|
3339
3444
|
* If not provided, the active organization will be used
|
|
3340
3445
|
*/
|
|
3341
|
-
organizationId:
|
|
3446
|
+
organizationId: z14.string().optional()
|
|
3342
3447
|
}),
|
|
3343
3448
|
use: [orgMiddleware, orgSessionMiddleware]
|
|
3344
3449
|
},
|
|
@@ -3401,16 +3506,19 @@ var updateMemberRole = createAuthEndpoint(
|
|
|
3401
3506
|
return ctx.json(updatedMember);
|
|
3402
3507
|
}
|
|
3403
3508
|
);
|
|
3509
|
+
|
|
3510
|
+
// src/plugins/organization/routes/crud-org.ts
|
|
3511
|
+
import { z as z15 } from "zod";
|
|
3404
3512
|
var createOrganization = createAuthEndpoint(
|
|
3405
3513
|
"/organization/create",
|
|
3406
3514
|
{
|
|
3407
3515
|
method: "POST",
|
|
3408
|
-
body:
|
|
3409
|
-
name:
|
|
3410
|
-
slug:
|
|
3411
|
-
userId:
|
|
3412
|
-
logo:
|
|
3413
|
-
metadata:
|
|
3516
|
+
body: z15.object({
|
|
3517
|
+
name: z15.string(),
|
|
3518
|
+
slug: z15.string(),
|
|
3519
|
+
userId: z15.string().optional(),
|
|
3520
|
+
logo: z15.string().optional(),
|
|
3521
|
+
metadata: z15.record(z15.string()).optional()
|
|
3414
3522
|
}),
|
|
3415
3523
|
use: [orgMiddleware, orgSessionMiddleware]
|
|
3416
3524
|
},
|
|
@@ -3471,12 +3579,12 @@ var updateOrganization = createAuthEndpoint(
|
|
|
3471
3579
|
"/organization/update",
|
|
3472
3580
|
{
|
|
3473
3581
|
method: "POST",
|
|
3474
|
-
body:
|
|
3475
|
-
data:
|
|
3476
|
-
name:
|
|
3477
|
-
slug:
|
|
3582
|
+
body: z15.object({
|
|
3583
|
+
data: z15.object({
|
|
3584
|
+
name: z15.string().optional(),
|
|
3585
|
+
slug: z15.string().optional()
|
|
3478
3586
|
}).partial(),
|
|
3479
|
-
orgId:
|
|
3587
|
+
orgId: z15.string().optional()
|
|
3480
3588
|
}),
|
|
3481
3589
|
requireHeaders: true,
|
|
3482
3590
|
use: [orgMiddleware]
|
|
@@ -3538,8 +3646,8 @@ var deleteOrganization = createAuthEndpoint(
|
|
|
3538
3646
|
"/organization/delete",
|
|
3539
3647
|
{
|
|
3540
3648
|
method: "POST",
|
|
3541
|
-
body:
|
|
3542
|
-
orgId:
|
|
3649
|
+
body: z15.object({
|
|
3650
|
+
orgId: z15.string()
|
|
3543
3651
|
}),
|
|
3544
3652
|
requireHeaders: true,
|
|
3545
3653
|
use: [orgMiddleware]
|
|
@@ -3604,8 +3712,8 @@ var getFullOrganization = createAuthEndpoint(
|
|
|
3604
3712
|
"/organization/get-full",
|
|
3605
3713
|
{
|
|
3606
3714
|
method: "GET",
|
|
3607
|
-
query:
|
|
3608
|
-
orgId:
|
|
3715
|
+
query: z15.object({
|
|
3716
|
+
orgId: z15.string().optional()
|
|
3609
3717
|
}),
|
|
3610
3718
|
requireHeaders: true,
|
|
3611
3719
|
use: [orgMiddleware, orgSessionMiddleware]
|
|
@@ -3641,8 +3749,8 @@ var setActiveOrganization = createAuthEndpoint(
|
|
|
3641
3749
|
"/organization/activate",
|
|
3642
3750
|
{
|
|
3643
3751
|
method: "POST",
|
|
3644
|
-
body:
|
|
3645
|
-
orgId:
|
|
3752
|
+
body: z15.object({
|
|
3753
|
+
orgId: z15.string().nullable().optional()
|
|
3646
3754
|
}),
|
|
3647
3755
|
use: [orgSessionMiddleware, orgMiddleware]
|
|
3648
3756
|
},
|
|
@@ -3738,14 +3846,14 @@ var organization = (options) => {
|
|
|
3738
3846
|
{
|
|
3739
3847
|
method: "POST",
|
|
3740
3848
|
requireHeaders: true,
|
|
3741
|
-
body:
|
|
3742
|
-
permission:
|
|
3849
|
+
body: z16.object({
|
|
3850
|
+
permission: z16.record(z16.string(), z16.array(z16.string()))
|
|
3743
3851
|
}),
|
|
3744
3852
|
use: [orgSessionMiddleware]
|
|
3745
3853
|
},
|
|
3746
3854
|
async (ctx) => {
|
|
3747
3855
|
if (!ctx.context.session.session.activeOrganizationId) {
|
|
3748
|
-
throw new
|
|
3856
|
+
throw new APIError7("BAD_REQUEST", {
|
|
3749
3857
|
message: "No active organization"
|
|
3750
3858
|
});
|
|
3751
3859
|
}
|
|
@@ -3755,7 +3863,7 @@ var organization = (options) => {
|
|
|
3755
3863
|
organizationId: ctx.context.session.session.activeOrganizationId || ""
|
|
3756
3864
|
});
|
|
3757
3865
|
if (!member) {
|
|
3758
|
-
throw new
|
|
3866
|
+
throw new APIError7("UNAUTHORIZED", {
|
|
3759
3867
|
message: "You are not a member of this organization"
|
|
3760
3868
|
});
|
|
3761
3869
|
}
|
|
@@ -3888,19 +3996,31 @@ var organization = (options) => {
|
|
|
3888
3996
|
};
|
|
3889
3997
|
};
|
|
3890
3998
|
|
|
3999
|
+
// src/plugins/two-factor/index.ts
|
|
4000
|
+
import { z as z21 } from "zod";
|
|
4001
|
+
|
|
4002
|
+
// src/plugins/two-factor/backup-codes/index.ts
|
|
4003
|
+
import { z as z18 } from "zod";
|
|
4004
|
+
|
|
4005
|
+
// src/plugins/two-factor/verify-middleware.ts
|
|
4006
|
+
import { APIError as APIError8 } from "better-call";
|
|
4007
|
+
|
|
3891
4008
|
// src/plugins/two-factor/constant.ts
|
|
3892
4009
|
var TWO_FACTOR_COOKIE_NAME = "two-factor";
|
|
3893
4010
|
var TRUST_DEVICE_COOKIE_NAME = "trust-device";
|
|
4011
|
+
|
|
4012
|
+
// src/plugins/two-factor/verify-middleware.ts
|
|
4013
|
+
import { z as z17 } from "zod";
|
|
3894
4014
|
var verifyTwoFactorMiddleware = createAuthMiddleware(
|
|
3895
4015
|
{
|
|
3896
|
-
body:
|
|
4016
|
+
body: z17.object({
|
|
3897
4017
|
/**
|
|
3898
4018
|
* if true, the device will be trusted
|
|
3899
4019
|
* for 30 days. It'll be refreshed on
|
|
3900
4020
|
* every sign in request within this time.
|
|
3901
4021
|
*/
|
|
3902
|
-
trustDevice:
|
|
3903
|
-
callbackURL:
|
|
4022
|
+
trustDevice: z17.boolean().optional(),
|
|
4023
|
+
callbackURL: z17.string().optional()
|
|
3904
4024
|
})
|
|
3905
4025
|
},
|
|
3906
4026
|
async (ctx) => {
|
|
@@ -3910,13 +4030,13 @@ var verifyTwoFactorMiddleware = createAuthMiddleware(
|
|
|
3910
4030
|
ctx.context.secret
|
|
3911
4031
|
);
|
|
3912
4032
|
if (!cookie) {
|
|
3913
|
-
throw new
|
|
4033
|
+
throw new APIError8("UNAUTHORIZED", {
|
|
3914
4034
|
message: "invalid two factor cookie"
|
|
3915
4035
|
});
|
|
3916
4036
|
}
|
|
3917
4037
|
const [userId, hash] = cookie.split("!");
|
|
3918
4038
|
if (!userId || !hash) {
|
|
3919
|
-
throw new
|
|
4039
|
+
throw new APIError8("UNAUTHORIZED", {
|
|
3920
4040
|
message: "invalid two factor cookie"
|
|
3921
4041
|
});
|
|
3922
4042
|
}
|
|
@@ -3930,7 +4050,7 @@ var verifyTwoFactorMiddleware = createAuthMiddleware(
|
|
|
3930
4050
|
]
|
|
3931
4051
|
});
|
|
3932
4052
|
if (!sessions.length) {
|
|
3933
|
-
throw new
|
|
4053
|
+
throw new APIError8("UNAUTHORIZED", {
|
|
3934
4054
|
message: "invalid session"
|
|
3935
4055
|
});
|
|
3936
4056
|
}
|
|
@@ -3938,7 +4058,7 @@ var verifyTwoFactorMiddleware = createAuthMiddleware(
|
|
|
3938
4058
|
(session) => session.expiresAt > /* @__PURE__ */ new Date()
|
|
3939
4059
|
);
|
|
3940
4060
|
if (!activeSessions) {
|
|
3941
|
-
throw new
|
|
4061
|
+
throw new APIError8("UNAUTHORIZED", {
|
|
3942
4062
|
message: "invalid session"
|
|
3943
4063
|
});
|
|
3944
4064
|
}
|
|
@@ -3954,7 +4074,7 @@ var verifyTwoFactorMiddleware = createAuthMiddleware(
|
|
|
3954
4074
|
]
|
|
3955
4075
|
});
|
|
3956
4076
|
if (!user) {
|
|
3957
|
-
throw new
|
|
4077
|
+
throw new APIError8("UNAUTHORIZED", {
|
|
3958
4078
|
message: "invalid session"
|
|
3959
4079
|
});
|
|
3960
4080
|
}
|
|
@@ -4010,7 +4130,7 @@ var verifyTwoFactorMiddleware = createAuthMiddleware(
|
|
|
4010
4130
|
};
|
|
4011
4131
|
}
|
|
4012
4132
|
}
|
|
4013
|
-
throw new
|
|
4133
|
+
throw new APIError8("UNAUTHORIZED", {
|
|
4014
4134
|
message: "invalid two factor authentication"
|
|
4015
4135
|
});
|
|
4016
4136
|
}
|
|
@@ -4018,8 +4138,8 @@ var verifyTwoFactorMiddleware = createAuthMiddleware(
|
|
|
4018
4138
|
|
|
4019
4139
|
// src/plugins/two-factor/backup-codes/index.ts
|
|
4020
4140
|
function generateBackupCodesFn(options) {
|
|
4021
|
-
return Array.from({ length: 10 }).fill(null).map(
|
|
4022
|
-
() => generateRandomString(10, alphabet("a-z", "0-9"))
|
|
4141
|
+
return Array.from({ length: options?.amount ?? 10 }).fill(null).map(
|
|
4142
|
+
() => generateRandomString(options?.length ?? 10, alphabet("a-z", "0-9"))
|
|
4023
4143
|
).map((code) => `${code.slice(0, 5)}-${code.slice(5)}`);
|
|
4024
4144
|
}
|
|
4025
4145
|
async function generateBackupCodes(secret, options) {
|
|
@@ -4046,7 +4166,7 @@ async function getBackupCodes(user, key) {
|
|
|
4046
4166
|
await symmetricDecrypt({ key, data: user.twoFactorBackupCodes })
|
|
4047
4167
|
).toString("utf-8");
|
|
4048
4168
|
const data = JSON.parse(secret);
|
|
4049
|
-
const result =
|
|
4169
|
+
const result = z18.array(z18.string()).safeParse(data);
|
|
4050
4170
|
if (result.success) {
|
|
4051
4171
|
return result.data;
|
|
4052
4172
|
}
|
|
@@ -4060,8 +4180,8 @@ var backupCode2fa = (options) => {
|
|
|
4060
4180
|
"/two-factor/verify-backup-code",
|
|
4061
4181
|
{
|
|
4062
4182
|
method: "POST",
|
|
4063
|
-
body:
|
|
4064
|
-
code:
|
|
4183
|
+
body: z18.object({
|
|
4184
|
+
code: z18.string()
|
|
4065
4185
|
}),
|
|
4066
4186
|
use: [verifyTwoFactorMiddleware]
|
|
4067
4187
|
},
|
|
@@ -4132,9 +4252,15 @@ var backupCode2fa = (options) => {
|
|
|
4132
4252
|
}
|
|
4133
4253
|
};
|
|
4134
4254
|
};
|
|
4255
|
+
|
|
4256
|
+
// src/plugins/two-factor/otp/index.ts
|
|
4257
|
+
import { APIError as APIError9 } from "better-call";
|
|
4258
|
+
import { TOTPController } from "oslo/otp";
|
|
4259
|
+
import { z as z19 } from "zod";
|
|
4260
|
+
import { TimeSpan as TimeSpan4 } from "oslo";
|
|
4135
4261
|
var otp2fa = (options) => {
|
|
4136
4262
|
const opts = {
|
|
4137
|
-
period: new
|
|
4263
|
+
period: new TimeSpan4(options?.period || 3, "m")
|
|
4138
4264
|
};
|
|
4139
4265
|
const totp = new TOTPController({
|
|
4140
4266
|
digits: 6,
|
|
@@ -4151,7 +4277,7 @@ var otp2fa = (options) => {
|
|
|
4151
4277
|
ctx.context.logger.error(
|
|
4152
4278
|
"send otp isn't configured. Please configure the send otp function on otp options."
|
|
4153
4279
|
);
|
|
4154
|
-
throw new
|
|
4280
|
+
throw new APIError9("BAD_REQUEST", {
|
|
4155
4281
|
message: "otp isn't configured"
|
|
4156
4282
|
});
|
|
4157
4283
|
}
|
|
@@ -4165,15 +4291,15 @@ var otp2fa = (options) => {
|
|
|
4165
4291
|
"/two-factor/verify-otp",
|
|
4166
4292
|
{
|
|
4167
4293
|
method: "POST",
|
|
4168
|
-
body:
|
|
4169
|
-
code:
|
|
4294
|
+
body: z19.object({
|
|
4295
|
+
code: z19.string()
|
|
4170
4296
|
}),
|
|
4171
4297
|
use: [verifyTwoFactorMiddleware]
|
|
4172
4298
|
},
|
|
4173
4299
|
async (ctx) => {
|
|
4174
4300
|
const user = ctx.context.session.user;
|
|
4175
4301
|
if (!user.twoFactorEnabled) {
|
|
4176
|
-
throw new
|
|
4302
|
+
throw new APIError9("BAD_REQUEST", {
|
|
4177
4303
|
message: "two factor isn't enabled"
|
|
4178
4304
|
});
|
|
4179
4305
|
}
|
|
@@ -4193,10 +4319,16 @@ var otp2fa = (options) => {
|
|
|
4193
4319
|
}
|
|
4194
4320
|
};
|
|
4195
4321
|
};
|
|
4322
|
+
|
|
4323
|
+
// src/plugins/two-factor/totp/index.ts
|
|
4324
|
+
import { APIError as APIError10 } from "better-call";
|
|
4325
|
+
import { TimeSpan as TimeSpan5 } from "oslo";
|
|
4326
|
+
import { TOTPController as TOTPController2, createTOTPKeyURI } from "oslo/otp";
|
|
4327
|
+
import { z as z20 } from "zod";
|
|
4196
4328
|
var totp2fa = (options) => {
|
|
4197
4329
|
const opts = {
|
|
4198
4330
|
digits: 6,
|
|
4199
|
-
period: new
|
|
4331
|
+
period: new TimeSpan5(options?.period || 30, "s")
|
|
4200
4332
|
};
|
|
4201
4333
|
const generateTOTP = createAuthEndpoint(
|
|
4202
4334
|
"/totp/generate",
|
|
@@ -4209,12 +4341,12 @@ var totp2fa = (options) => {
|
|
|
4209
4341
|
ctx.context.logger.error(
|
|
4210
4342
|
"totp isn't configured. please pass totp option on two factor plugin to enable totp"
|
|
4211
4343
|
);
|
|
4212
|
-
throw new
|
|
4344
|
+
throw new APIError10("BAD_REQUEST", {
|
|
4213
4345
|
message: "totp isn't configured"
|
|
4214
4346
|
});
|
|
4215
4347
|
}
|
|
4216
4348
|
const session = ctx.context.session.user;
|
|
4217
|
-
const totp = new
|
|
4349
|
+
const totp = new TOTPController2(opts);
|
|
4218
4350
|
const code = await totp.generate(Buffer.from(session.twoFactorSecret));
|
|
4219
4351
|
return { code };
|
|
4220
4352
|
}
|
|
@@ -4230,13 +4362,13 @@ var totp2fa = (options) => {
|
|
|
4230
4362
|
ctx.context.logger.error(
|
|
4231
4363
|
"totp isn't configured. please pass totp option on two factor plugin to enable totp"
|
|
4232
4364
|
);
|
|
4233
|
-
throw new
|
|
4365
|
+
throw new APIError10("BAD_REQUEST", {
|
|
4234
4366
|
message: "totp isn't configured"
|
|
4235
4367
|
});
|
|
4236
4368
|
}
|
|
4237
4369
|
const user = ctx.context.session.user;
|
|
4238
4370
|
if (!user.twoFactorSecret) {
|
|
4239
|
-
throw new
|
|
4371
|
+
throw new APIError10("BAD_REQUEST", {
|
|
4240
4372
|
message: "totp isn't enabled"
|
|
4241
4373
|
});
|
|
4242
4374
|
}
|
|
@@ -4254,9 +4386,9 @@ var totp2fa = (options) => {
|
|
|
4254
4386
|
"/two-factor/verify-totp",
|
|
4255
4387
|
{
|
|
4256
4388
|
method: "POST",
|
|
4257
|
-
body:
|
|
4258
|
-
code:
|
|
4259
|
-
callbackURL:
|
|
4389
|
+
body: z20.object({
|
|
4390
|
+
code: z20.string(),
|
|
4391
|
+
callbackURL: z20.string().optional()
|
|
4260
4392
|
}),
|
|
4261
4393
|
use: [verifyTwoFactorMiddleware]
|
|
4262
4394
|
},
|
|
@@ -4265,11 +4397,11 @@ var totp2fa = (options) => {
|
|
|
4265
4397
|
ctx.context.logger.error(
|
|
4266
4398
|
"totp isn't configured. please pass totp option on two factor plugin to enable totp"
|
|
4267
4399
|
);
|
|
4268
|
-
throw new
|
|
4400
|
+
throw new APIError10("BAD_REQUEST", {
|
|
4269
4401
|
message: "totp isn't configured"
|
|
4270
4402
|
});
|
|
4271
4403
|
}
|
|
4272
|
-
const totp = new
|
|
4404
|
+
const totp = new TOTPController2(opts);
|
|
4273
4405
|
const secret = Buffer.from(
|
|
4274
4406
|
await symmetricDecrypt({
|
|
4275
4407
|
key: ctx.context.secret,
|
|
@@ -4293,6 +4425,23 @@ var totp2fa = (options) => {
|
|
|
4293
4425
|
};
|
|
4294
4426
|
};
|
|
4295
4427
|
|
|
4428
|
+
// src/utils/password.ts
|
|
4429
|
+
async function validatePassword(ctx, data) {
|
|
4430
|
+
const accounts = await ctx.context.internalAdapter.findAccounts(data.userId);
|
|
4431
|
+
const credentialAccount = accounts?.find(
|
|
4432
|
+
(account) => account.providerId === "credential"
|
|
4433
|
+
);
|
|
4434
|
+
const currentPassword = credentialAccount?.password;
|
|
4435
|
+
if (!credentialAccount || !currentPassword) {
|
|
4436
|
+
return false;
|
|
4437
|
+
}
|
|
4438
|
+
const compare = await ctx.context.password.verify(
|
|
4439
|
+
currentPassword,
|
|
4440
|
+
data.password
|
|
4441
|
+
);
|
|
4442
|
+
return compare;
|
|
4443
|
+
}
|
|
4444
|
+
|
|
4296
4445
|
// src/plugins/two-factor/client.ts
|
|
4297
4446
|
var twoFactorClient = (options = {
|
|
4298
4447
|
redirect: true,
|
|
@@ -4350,8 +4499,8 @@ var twoFactor = (options) => {
|
|
|
4350
4499
|
"/two-factor/enable",
|
|
4351
4500
|
{
|
|
4352
4501
|
method: "POST",
|
|
4353
|
-
body:
|
|
4354
|
-
password:
|
|
4502
|
+
body: z21.object({
|
|
4503
|
+
password: z21.string().min(8)
|
|
4355
4504
|
}),
|
|
4356
4505
|
use: [sessionMiddleware]
|
|
4357
4506
|
},
|
|
@@ -4403,8 +4552,8 @@ var twoFactor = (options) => {
|
|
|
4403
4552
|
"/two-factor/disable",
|
|
4404
4553
|
{
|
|
4405
4554
|
method: "POST",
|
|
4406
|
-
body:
|
|
4407
|
-
password:
|
|
4555
|
+
body: z21.object({
|
|
4556
|
+
password: z21.string().min(8)
|
|
4408
4557
|
}),
|
|
4409
4558
|
use: [sessionMiddleware]
|
|
4410
4559
|
},
|
|
@@ -4557,11 +4706,43 @@ var twoFactor = (options) => {
|
|
|
4557
4706
|
]
|
|
4558
4707
|
};
|
|
4559
4708
|
};
|
|
4709
|
+
|
|
4710
|
+
// src/plugins/passkey/index.ts
|
|
4711
|
+
import {
|
|
4712
|
+
generateAuthenticationOptions,
|
|
4713
|
+
generateRegistrationOptions,
|
|
4714
|
+
verifyAuthenticationResponse,
|
|
4715
|
+
verifyRegistrationResponse
|
|
4716
|
+
} from "@simplewebauthn/server";
|
|
4717
|
+
import { APIError as APIError11 } from "better-call";
|
|
4718
|
+
import { z as z22 } from "zod";
|
|
4719
|
+
|
|
4720
|
+
// src/plugins/passkey/client.ts
|
|
4721
|
+
import {
|
|
4722
|
+
WebAuthnError,
|
|
4723
|
+
startAuthentication,
|
|
4724
|
+
startRegistration
|
|
4725
|
+
} from "@simplewebauthn/browser";
|
|
4726
|
+
|
|
4727
|
+
// src/client/config.ts
|
|
4728
|
+
import { createFetch } from "@better-fetch/fetch";
|
|
4729
|
+
import "nanostores";
|
|
4730
|
+
|
|
4731
|
+
// src/client/fetch-plugins.ts
|
|
4732
|
+
import { betterFetch as betterFetch9 } from "@better-fetch/fetch";
|
|
4733
|
+
|
|
4734
|
+
// src/client/session-atom.ts
|
|
4735
|
+
import { atom as atom2 } from "nanostores";
|
|
4736
|
+
|
|
4737
|
+
// src/client/query.ts
|
|
4738
|
+
import "@better-fetch/fetch";
|
|
4739
|
+
import { atom, onMount } from "nanostores";
|
|
4560
4740
|
var useAuthQuery = (initializedAtom, path, $fetch, options) => {
|
|
4561
4741
|
const value = atom({
|
|
4562
4742
|
data: null,
|
|
4563
4743
|
error: null,
|
|
4564
|
-
isPending: false
|
|
4744
|
+
isPending: false,
|
|
4745
|
+
isRefetching: false
|
|
4565
4746
|
});
|
|
4566
4747
|
const fn = () => {
|
|
4567
4748
|
const opts = typeof options === "function" ? options({
|
|
@@ -4575,24 +4756,27 @@ var useAuthQuery = (initializedAtom, path, $fetch, options) => {
|
|
|
4575
4756
|
value.set({
|
|
4576
4757
|
data: context.data,
|
|
4577
4758
|
error: null,
|
|
4578
|
-
isPending: false
|
|
4759
|
+
isPending: false,
|
|
4760
|
+
isRefetching: false
|
|
4579
4761
|
});
|
|
4580
4762
|
await opts?.onSuccess?.(context);
|
|
4581
4763
|
},
|
|
4582
4764
|
async onError(context) {
|
|
4583
4765
|
value.set({
|
|
4584
4766
|
error: context.error,
|
|
4585
|
-
data:
|
|
4586
|
-
isPending: false
|
|
4767
|
+
data: value.get().data,
|
|
4768
|
+
isPending: false,
|
|
4769
|
+
isRefetching: false
|
|
4587
4770
|
});
|
|
4588
4771
|
await opts?.onError?.(context);
|
|
4589
4772
|
},
|
|
4590
4773
|
async onRequest(context) {
|
|
4591
4774
|
const currentValue = value.get();
|
|
4592
4775
|
value.set({
|
|
4593
|
-
isPending:
|
|
4776
|
+
isPending: currentValue.data === null,
|
|
4594
4777
|
data: currentValue.data,
|
|
4595
|
-
error:
|
|
4778
|
+
error: null,
|
|
4779
|
+
isRefetching: true
|
|
4596
4780
|
});
|
|
4597
4781
|
await opts?.onRequest?.(context);
|
|
4598
4782
|
}
|
|
@@ -4618,6 +4802,9 @@ var useAuthQuery = (initializedAtom, path, $fetch, options) => {
|
|
|
4618
4802
|
}
|
|
4619
4803
|
return value;
|
|
4620
4804
|
};
|
|
4805
|
+
|
|
4806
|
+
// src/plugins/passkey/client.ts
|
|
4807
|
+
import { atom as atom3 } from "nanostores";
|
|
4621
4808
|
var getPasskeyActions = ($fetch, {
|
|
4622
4809
|
_listPasskeys
|
|
4623
4810
|
}) => {
|
|
@@ -4739,7 +4926,7 @@ var getPasskeyActions = ($fetch, {
|
|
|
4739
4926
|
};
|
|
4740
4927
|
};
|
|
4741
4928
|
var passkeyClient = () => {
|
|
4742
|
-
const _listPasskeys =
|
|
4929
|
+
const _listPasskeys = atom3();
|
|
4743
4930
|
return {
|
|
4744
4931
|
id: "passkey",
|
|
4745
4932
|
$InferServerPlugin: {},
|
|
@@ -4866,9 +5053,9 @@ var passkey = (options) => {
|
|
|
4866
5053
|
"/passkey/generate-authenticate-options",
|
|
4867
5054
|
{
|
|
4868
5055
|
method: "POST",
|
|
4869
|
-
body:
|
|
4870
|
-
email:
|
|
4871
|
-
callbackURL:
|
|
5056
|
+
body: z22.object({
|
|
5057
|
+
email: z22.string().optional(),
|
|
5058
|
+
callbackURL: z22.string().optional()
|
|
4872
5059
|
}).optional()
|
|
4873
5060
|
},
|
|
4874
5061
|
async (ctx) => {
|
|
@@ -4924,9 +5111,9 @@ var passkey = (options) => {
|
|
|
4924
5111
|
"/passkey/verify-registration",
|
|
4925
5112
|
{
|
|
4926
5113
|
method: "POST",
|
|
4927
|
-
body:
|
|
4928
|
-
response:
|
|
4929
|
-
name:
|
|
5114
|
+
body: z22.object({
|
|
5115
|
+
response: z22.any(),
|
|
5116
|
+
name: z22.string().optional()
|
|
4930
5117
|
}),
|
|
4931
5118
|
use: [sessionMiddleware]
|
|
4932
5119
|
},
|
|
@@ -4951,7 +5138,7 @@ var passkey = (options) => {
|
|
|
4951
5138
|
challengeString
|
|
4952
5139
|
);
|
|
4953
5140
|
if (userData.id !== ctx.context.session.user.id) {
|
|
4954
|
-
throw new
|
|
5141
|
+
throw new APIError11("UNAUTHORIZED", {
|
|
4955
5142
|
message: "You are not authorized to register this passkey"
|
|
4956
5143
|
});
|
|
4957
5144
|
}
|
|
@@ -5011,8 +5198,8 @@ var passkey = (options) => {
|
|
|
5011
5198
|
"/passkey/verify-authentication",
|
|
5012
5199
|
{
|
|
5013
5200
|
method: "POST",
|
|
5014
|
-
body:
|
|
5015
|
-
response:
|
|
5201
|
+
body: z22.object({
|
|
5202
|
+
response: z22.any()
|
|
5016
5203
|
})
|
|
5017
5204
|
},
|
|
5018
5205
|
async (ctx) => {
|
|
@@ -5148,8 +5335,8 @@ var passkey = (options) => {
|
|
|
5148
5335
|
"/passkey/delete-passkey",
|
|
5149
5336
|
{
|
|
5150
5337
|
method: "POST",
|
|
5151
|
-
body:
|
|
5152
|
-
id:
|
|
5338
|
+
body: z22.object({
|
|
5339
|
+
id: z22.string()
|
|
5153
5340
|
}),
|
|
5154
5341
|
use: [sessionMiddleware]
|
|
5155
5342
|
},
|
|
@@ -5218,6 +5405,10 @@ var passkey = (options) => {
|
|
|
5218
5405
|
}
|
|
5219
5406
|
};
|
|
5220
5407
|
};
|
|
5408
|
+
|
|
5409
|
+
// src/plugins/username/index.ts
|
|
5410
|
+
import { z as z23 } from "zod";
|
|
5411
|
+
import { APIError as APIError12 } from "better-call";
|
|
5221
5412
|
var username = () => {
|
|
5222
5413
|
return {
|
|
5223
5414
|
id: "username",
|
|
@@ -5226,11 +5417,11 @@ var username = () => {
|
|
|
5226
5417
|
"/sign-in/username",
|
|
5227
5418
|
{
|
|
5228
5419
|
method: "POST",
|
|
5229
|
-
body:
|
|
5230
|
-
username:
|
|
5231
|
-
password:
|
|
5232
|
-
dontRememberMe:
|
|
5233
|
-
callbackURL:
|
|
5420
|
+
body: z23.object({
|
|
5421
|
+
username: z23.string(),
|
|
5422
|
+
password: z23.string(),
|
|
5423
|
+
dontRememberMe: z23.boolean().optional(),
|
|
5424
|
+
callbackURL: z23.string().optional()
|
|
5234
5425
|
})
|
|
5235
5426
|
},
|
|
5236
5427
|
async (ctx) => {
|
|
@@ -5246,7 +5437,7 @@ var username = () => {
|
|
|
5246
5437
|
if (!user) {
|
|
5247
5438
|
await ctx.context.password.hash(ctx.body.password);
|
|
5248
5439
|
ctx.context.logger.error("User not found", { username });
|
|
5249
|
-
throw new
|
|
5440
|
+
throw new APIError12("UNAUTHORIZED", {
|
|
5250
5441
|
message: "Invalid email or password"
|
|
5251
5442
|
});
|
|
5252
5443
|
}
|
|
@@ -5264,14 +5455,14 @@ var username = () => {
|
|
|
5264
5455
|
]
|
|
5265
5456
|
});
|
|
5266
5457
|
if (!account) {
|
|
5267
|
-
throw new
|
|
5458
|
+
throw new APIError12("UNAUTHORIZED", {
|
|
5268
5459
|
message: "Invalid email or password"
|
|
5269
5460
|
});
|
|
5270
5461
|
}
|
|
5271
5462
|
const currentPassword = account?.password;
|
|
5272
5463
|
if (!currentPassword) {
|
|
5273
5464
|
ctx.context.logger.error("Password not found", { username });
|
|
5274
|
-
throw new
|
|
5465
|
+
throw new APIError12("UNAUTHORIZED", {
|
|
5275
5466
|
message: "Unexpected error"
|
|
5276
5467
|
});
|
|
5277
5468
|
}
|
|
@@ -5281,7 +5472,7 @@ var username = () => {
|
|
|
5281
5472
|
);
|
|
5282
5473
|
if (!validPassword) {
|
|
5283
5474
|
ctx.context.logger.error("Invalid password");
|
|
5284
|
-
throw new
|
|
5475
|
+
throw new APIError12("UNAUTHORIZED", {
|
|
5285
5476
|
message: "Invalid email or password"
|
|
5286
5477
|
});
|
|
5287
5478
|
}
|
|
@@ -5319,13 +5510,13 @@ var username = () => {
|
|
|
5319
5510
|
"/sign-up/username",
|
|
5320
5511
|
{
|
|
5321
5512
|
method: "POST",
|
|
5322
|
-
body:
|
|
5323
|
-
username:
|
|
5324
|
-
name:
|
|
5325
|
-
email:
|
|
5326
|
-
password:
|
|
5327
|
-
image:
|
|
5328
|
-
callbackURL:
|
|
5513
|
+
body: z23.object({
|
|
5514
|
+
username: z23.string().min(3).max(20),
|
|
5515
|
+
name: z23.string(),
|
|
5516
|
+
email: z23.string().email(),
|
|
5517
|
+
password: z23.string(),
|
|
5518
|
+
image: z23.string().optional(),
|
|
5519
|
+
callbackURL: z23.string().optional()
|
|
5329
5520
|
})
|
|
5330
5521
|
},
|
|
5331
5522
|
async (ctx) => {
|
|
@@ -5385,6 +5576,9 @@ var username = () => {
|
|
|
5385
5576
|
}
|
|
5386
5577
|
};
|
|
5387
5578
|
};
|
|
5579
|
+
|
|
5580
|
+
// src/plugins/bearer/index.ts
|
|
5581
|
+
import { serializeSigned } from "better-call";
|
|
5388
5582
|
var bearer = () => {
|
|
5389
5583
|
return {
|
|
5390
5584
|
id: "bearer",
|
|
@@ -5415,6 +5609,11 @@ var bearer = () => {
|
|
|
5415
5609
|
}
|
|
5416
5610
|
};
|
|
5417
5611
|
};
|
|
5612
|
+
|
|
5613
|
+
// src/plugins/magic-link/index.ts
|
|
5614
|
+
import { z as z24 } from "zod";
|
|
5615
|
+
import { APIError as APIError13 } from "better-call";
|
|
5616
|
+
import { validateJWT as validateJWT3 } from "oslo/jwt";
|
|
5418
5617
|
var magicLink = (options) => {
|
|
5419
5618
|
return {
|
|
5420
5619
|
id: "magic-link",
|
|
@@ -5424,17 +5623,17 @@ var magicLink = (options) => {
|
|
|
5424
5623
|
{
|
|
5425
5624
|
method: "POST",
|
|
5426
5625
|
requireHeaders: true,
|
|
5427
|
-
body:
|
|
5428
|
-
email:
|
|
5429
|
-
callbackURL:
|
|
5430
|
-
currentURL:
|
|
5626
|
+
body: z24.object({
|
|
5627
|
+
email: z24.string().email(),
|
|
5628
|
+
callbackURL: z24.string().optional(),
|
|
5629
|
+
currentURL: z24.string().optional()
|
|
5431
5630
|
})
|
|
5432
5631
|
},
|
|
5433
5632
|
async (ctx) => {
|
|
5434
5633
|
const { email } = ctx.body;
|
|
5435
5634
|
const user = await ctx.context.internalAdapter.findUserByEmail(email);
|
|
5436
5635
|
if (!user) {
|
|
5437
|
-
throw new
|
|
5636
|
+
throw new APIError13("UNAUTHORIZED", {
|
|
5438
5637
|
message: "User not found"
|
|
5439
5638
|
});
|
|
5440
5639
|
}
|
|
@@ -5451,7 +5650,7 @@ var magicLink = (options) => {
|
|
|
5451
5650
|
});
|
|
5452
5651
|
} catch (e) {
|
|
5453
5652
|
ctx.context.logger.error("Failed to send magic link", e);
|
|
5454
|
-
throw new
|
|
5653
|
+
throw new APIError13("INTERNAL_SERVER_ERROR", {
|
|
5455
5654
|
message: "Failed to send magic link"
|
|
5456
5655
|
});
|
|
5457
5656
|
}
|
|
@@ -5464,9 +5663,9 @@ var magicLink = (options) => {
|
|
|
5464
5663
|
"/magic-link/verify",
|
|
5465
5664
|
{
|
|
5466
5665
|
method: "GET",
|
|
5467
|
-
query:
|
|
5468
|
-
token:
|
|
5469
|
-
callbackURL:
|
|
5666
|
+
query: z24.object({
|
|
5667
|
+
token: z24.string(),
|
|
5668
|
+
callbackURL: z24.string().optional()
|
|
5470
5669
|
}),
|
|
5471
5670
|
requireHeaders: true
|
|
5472
5671
|
},
|
|
@@ -5474,7 +5673,7 @@ var magicLink = (options) => {
|
|
|
5474
5673
|
const { token, callbackURL } = ctx.query;
|
|
5475
5674
|
let jwt;
|
|
5476
5675
|
try {
|
|
5477
|
-
jwt = await
|
|
5676
|
+
jwt = await validateJWT3(
|
|
5478
5677
|
"HS256",
|
|
5479
5678
|
Buffer.from(ctx.context.secret),
|
|
5480
5679
|
token
|
|
@@ -5492,8 +5691,8 @@ var magicLink = (options) => {
|
|
|
5492
5691
|
}
|
|
5493
5692
|
});
|
|
5494
5693
|
}
|
|
5495
|
-
const schema =
|
|
5496
|
-
email:
|
|
5694
|
+
const schema = z24.object({
|
|
5695
|
+
email: z24.string().email()
|
|
5497
5696
|
});
|
|
5498
5697
|
const parsed = schema.parse(jwt.payload);
|
|
5499
5698
|
const user = await ctx.context.internalAdapter.findUserByEmail(
|
|
@@ -5539,6 +5738,10 @@ var magicLink = (options) => {
|
|
|
5539
5738
|
}
|
|
5540
5739
|
};
|
|
5541
5740
|
};
|
|
5741
|
+
|
|
5742
|
+
// src/plugins/phone-number/index.ts
|
|
5743
|
+
import { z as z25 } from "zod";
|
|
5744
|
+
import { APIError as APIError14 } from "better-call";
|
|
5542
5745
|
function generateOTP(size) {
|
|
5543
5746
|
return generateRandomString(size, alphabet("0-9"));
|
|
5544
5747
|
}
|
|
@@ -5560,11 +5763,11 @@ var phoneNumber = (options) => {
|
|
|
5560
5763
|
"/sign-in/phone-number",
|
|
5561
5764
|
{
|
|
5562
5765
|
method: "POST",
|
|
5563
|
-
body:
|
|
5564
|
-
phoneNumber:
|
|
5565
|
-
password:
|
|
5566
|
-
dontRememberMe:
|
|
5567
|
-
callbackURL:
|
|
5766
|
+
body: z25.object({
|
|
5767
|
+
phoneNumber: z25.string(),
|
|
5768
|
+
password: z25.string(),
|
|
5769
|
+
dontRememberMe: z25.boolean().optional(),
|
|
5770
|
+
callbackURL: z25.string().optional()
|
|
5568
5771
|
})
|
|
5569
5772
|
},
|
|
5570
5773
|
async (ctx) => {
|
|
@@ -5579,7 +5782,7 @@ var phoneNumber = (options) => {
|
|
|
5579
5782
|
});
|
|
5580
5783
|
if (!user) {
|
|
5581
5784
|
await ctx.context.password.hash(ctx.body.password);
|
|
5582
|
-
throw new
|
|
5785
|
+
throw new APIError14("UNAUTHORIZED", {
|
|
5583
5786
|
message: "Invalid email or password"
|
|
5584
5787
|
});
|
|
5585
5788
|
}
|
|
@@ -5597,7 +5800,7 @@ var phoneNumber = (options) => {
|
|
|
5597
5800
|
]
|
|
5598
5801
|
});
|
|
5599
5802
|
if (!account) {
|
|
5600
|
-
throw new
|
|
5803
|
+
throw new APIError14("UNAUTHORIZED", {
|
|
5601
5804
|
message: "Invalid email or password"
|
|
5602
5805
|
});
|
|
5603
5806
|
}
|
|
@@ -5607,7 +5810,7 @@ var phoneNumber = (options) => {
|
|
|
5607
5810
|
"Unexpectedly password is missing for the user",
|
|
5608
5811
|
user
|
|
5609
5812
|
);
|
|
5610
|
-
throw new
|
|
5813
|
+
throw new APIError14("UNAUTHORIZED", {
|
|
5611
5814
|
message: "Unexpected error"
|
|
5612
5815
|
});
|
|
5613
5816
|
}
|
|
@@ -5617,7 +5820,7 @@ var phoneNumber = (options) => {
|
|
|
5617
5820
|
);
|
|
5618
5821
|
if (!validPassword) {
|
|
5619
5822
|
ctx.context.logger.error("Invalid password");
|
|
5620
|
-
throw new
|
|
5823
|
+
throw new APIError14("UNAUTHORIZED", {
|
|
5621
5824
|
message: "Invalid email or password"
|
|
5622
5825
|
});
|
|
5623
5826
|
}
|
|
@@ -5655,13 +5858,13 @@ var phoneNumber = (options) => {
|
|
|
5655
5858
|
"/sign-up/phone-number",
|
|
5656
5859
|
{
|
|
5657
5860
|
method: "POST",
|
|
5658
|
-
body:
|
|
5659
|
-
phoneNumber:
|
|
5660
|
-
name:
|
|
5661
|
-
email:
|
|
5662
|
-
password:
|
|
5663
|
-
image:
|
|
5664
|
-
callbackURL:
|
|
5861
|
+
body: z25.object({
|
|
5862
|
+
phoneNumber: z25.string().min(3).max(20),
|
|
5863
|
+
name: z25.string(),
|
|
5864
|
+
email: z25.string().email(),
|
|
5865
|
+
password: z25.string(),
|
|
5866
|
+
image: z25.string().optional(),
|
|
5867
|
+
callbackURL: z25.string().optional()
|
|
5665
5868
|
})
|
|
5666
5869
|
},
|
|
5667
5870
|
async (ctx) => {
|
|
@@ -5682,7 +5885,7 @@ var phoneNumber = (options) => {
|
|
|
5682
5885
|
if (options?.otp?.sendOTPonSignUp) {
|
|
5683
5886
|
if (!options.otp.sendOTP) {
|
|
5684
5887
|
logger.warn("sendOTP not implemented");
|
|
5685
|
-
throw new
|
|
5888
|
+
throw new APIError14("NOT_IMPLEMENTED", {
|
|
5686
5889
|
message: "sendOTP not implemented"
|
|
5687
5890
|
});
|
|
5688
5891
|
}
|
|
@@ -5725,14 +5928,14 @@ var phoneNumber = (options) => {
|
|
|
5725
5928
|
"/phone-number/send-verification-code",
|
|
5726
5929
|
{
|
|
5727
5930
|
method: "POST",
|
|
5728
|
-
body:
|
|
5729
|
-
phoneNumber:
|
|
5931
|
+
body: z25.object({
|
|
5932
|
+
phoneNumber: z25.string()
|
|
5730
5933
|
})
|
|
5731
5934
|
},
|
|
5732
5935
|
async (ctx) => {
|
|
5733
5936
|
if (!options?.otp?.sendOTP) {
|
|
5734
5937
|
logger.warn("sendOTP not implemented");
|
|
5735
|
-
throw new
|
|
5938
|
+
throw new APIError14("NOT_IMPLEMENTED", {
|
|
5736
5939
|
message: "sendOTP not implemented"
|
|
5737
5940
|
});
|
|
5738
5941
|
}
|
|
@@ -5757,9 +5960,9 @@ var phoneNumber = (options) => {
|
|
|
5757
5960
|
"/phone-number/verify",
|
|
5758
5961
|
{
|
|
5759
5962
|
method: "POST",
|
|
5760
|
-
body:
|
|
5761
|
-
phoneNumber:
|
|
5762
|
-
code:
|
|
5963
|
+
body: z25.object({
|
|
5964
|
+
phoneNumber: z25.string(),
|
|
5965
|
+
code: z25.string()
|
|
5763
5966
|
})
|
|
5764
5967
|
},
|
|
5765
5968
|
async (ctx) => {
|
|
@@ -5802,7 +6005,7 @@ var phoneNumber = (options) => {
|
|
|
5802
6005
|
]
|
|
5803
6006
|
});
|
|
5804
6007
|
if (!user) {
|
|
5805
|
-
throw new
|
|
6008
|
+
throw new APIError14("NOT_FOUND", {
|
|
5806
6009
|
message: "User with phone number not found"
|
|
5807
6010
|
});
|
|
5808
6011
|
}
|
|
@@ -5841,8 +6044,8 @@ var phoneNumber = (options) => {
|
|
|
5841
6044
|
"/phone-number/update",
|
|
5842
6045
|
{
|
|
5843
6046
|
method: "POST",
|
|
5844
|
-
body:
|
|
5845
|
-
phoneNumber:
|
|
6047
|
+
body: z25.object({
|
|
6048
|
+
phoneNumber: z25.string()
|
|
5846
6049
|
}),
|
|
5847
6050
|
use: [sessionMiddleware]
|
|
5848
6051
|
},
|
|
@@ -5850,7 +6053,7 @@ var phoneNumber = (options) => {
|
|
|
5850
6053
|
if (options?.otp?.sendOTPonUpdate) {
|
|
5851
6054
|
if (!options.otp.sendOTP) {
|
|
5852
6055
|
logger.warn("sendOTP not implemented");
|
|
5853
|
-
throw new
|
|
6056
|
+
throw new APIError14("NOT_IMPLEMENTED", {
|
|
5854
6057
|
message: "sendOTP not implemented"
|
|
5855
6058
|
});
|
|
5856
6059
|
}
|
|
@@ -5897,5 +6100,20 @@ var phoneNumber = (options) => {
|
|
|
5897
6100
|
}
|
|
5898
6101
|
};
|
|
5899
6102
|
};
|
|
5900
|
-
|
|
5901
|
-
|
|
6103
|
+
export {
|
|
6104
|
+
HIDE_METADATA,
|
|
6105
|
+
access_exports as ac,
|
|
6106
|
+
bearer,
|
|
6107
|
+
createAuthEndpoint,
|
|
6108
|
+
createAuthMiddleware,
|
|
6109
|
+
getPasskeyActions,
|
|
6110
|
+
magicLink,
|
|
6111
|
+
optionsMiddleware,
|
|
6112
|
+
organization,
|
|
6113
|
+
passkey,
|
|
6114
|
+
passkeyClient,
|
|
6115
|
+
phoneNumber,
|
|
6116
|
+
twoFactor,
|
|
6117
|
+
twoFactorClient,
|
|
6118
|
+
username
|
|
6119
|
+
};
|