migrate auth v2 code
This commit is contained in:
@@ -1,35 +1,94 @@
|
||||
import { fail, isRedirect, redirect } from '@sveltejs/kit';
|
||||
import { signup, setSessionCookie, setPbTokenCookie } from '$lib/server/auth';
|
||||
import { fail, redirect } from '@sveltejs/kit';
|
||||
import type { RequestEvent } from '@sveltejs/kit';
|
||||
import { pbAdmin } from '$lib/server/pocketbase';
|
||||
import { createPbClient } from '$lib/server/pocketbase';
|
||||
import { setSessionCookie } from '$lib/server/session';
|
||||
import { issueAccess } from '$lib/server/member-otp';
|
||||
import { slugify, handle, famUsername, handleOf } from '@shared/slugify';
|
||||
|
||||
class SignupError extends Error {}
|
||||
|
||||
export const actions = {
|
||||
default: async (event) => {
|
||||
// Step 1 — create the family + parent (admin) user, mint their session.
|
||||
// The parent's human-entered name is kept as the display `name`; their PB
|
||||
// `username` is `{famSlug}:{handle}` (globally unique, handle = no whitespace).
|
||||
signup: async (event) => {
|
||||
const fd = await event.request.formData();
|
||||
const famName = fd.get('familyName') as string;
|
||||
const yourName = (fd.get('yourName') as string) || '';
|
||||
const email = fd.get('email') as string;
|
||||
const password = fd.get('password') as string;
|
||||
const famName = fd.get('famName') as string;
|
||||
const parentName = fd.get('parentName') as string;
|
||||
|
||||
if (!email || !password || !famName) {
|
||||
return fail(400, { error: 'All fields required', email, famName });
|
||||
if (!famName || !yourName || !email || !password) {
|
||||
return fail(400, { message: 'All fields required', famName, email });
|
||||
}
|
||||
if (password.length < 8) {
|
||||
return fail(400, { error: 'Password must be at least 8 characters', email, famName });
|
||||
return fail(400, { message: 'Password must be at least 8 characters', famName, email });
|
||||
}
|
||||
|
||||
const parentName = yourName.trim();
|
||||
const slug = slugify(famName);
|
||||
const handleName = handle(parentName) || 'admin';
|
||||
const username = famUsername(slug, handleName);
|
||||
|
||||
try {
|
||||
const result = await signup(email, password, famName, parentName || email.split('@')[0]);
|
||||
setSessionCookie(event, {
|
||||
famId: result.famId,
|
||||
userId: result.userId,
|
||||
famSlug: result.famSlug,
|
||||
memberName: result.memberName,
|
||||
role: result.role,
|
||||
const fam = await pbAdmin.create('fams', {
|
||||
name: famName,
|
||||
slug,
|
||||
timezone: 'auto'
|
||||
});
|
||||
setPbTokenCookie(event, result.token);
|
||||
throw redirect(303, `/${result.famSlug}/${result.memberName}`);
|
||||
const user = await pbAdmin.create('users', {
|
||||
username,
|
||||
name: parentName,
|
||||
email,
|
||||
password,
|
||||
passwordConfirm: password,
|
||||
emailVisibility: false,
|
||||
famId: fam.id,
|
||||
role: 'parent'
|
||||
});
|
||||
await pbAdmin.create('settings', { famId: fam.id });
|
||||
} catch (e) {
|
||||
if (isRedirect(e)) throw e;
|
||||
return fail(400, { error: e instanceof Error ? e.message : 'Signup failed', email, famName });
|
||||
throw new SignupError(
|
||||
`Could not create account — ${e instanceof Error ? e.message : 'please try again'}`
|
||||
);
|
||||
}
|
||||
|
||||
// Auth as the new parent to mint their JWT, then move to the child step.
|
||||
const authResult = await createPbClient()
|
||||
.collection('users')
|
||||
.authWithPassword(email, password)
|
||||
.catch(() => null);
|
||||
if (authResult?.token) setSessionCookie(event.cookies, authResult.token);
|
||||
|
||||
// `username` here is the handle (URL segment), not the composite.
|
||||
return { success: true, famSlug: slug, username: handleName };
|
||||
},
|
||||
|
||||
// Step 2 — optionally add a child now; issues their OTP join code.
|
||||
child: async (event: RequestEvent) => {
|
||||
const user = requireUser(event);
|
||||
const fd = await event.request.formData();
|
||||
const name = ((fd.get('member') as string) || '').trim();
|
||||
|
||||
const fam = await pbAdmin.getOne('fams', user.famId);
|
||||
const famSlug = fam?.slug || user.famId;
|
||||
|
||||
if (!name) {
|
||||
return { success: true, famSlug, username: handleOf(user.username) };
|
||||
}
|
||||
|
||||
const { otp, joinUrl } = await issueAccess({
|
||||
famId: user.famId,
|
||||
famSlug,
|
||||
name
|
||||
});
|
||||
|
||||
return { success: true, code: otp, joinUrl, famSlug, username: handleOf(user.username) };
|
||||
}
|
||||
};
|
||||
|
||||
function requireUser(event: RequestEvent) {
|
||||
if (!event.locals.user) throw redirect(303, '/signup');
|
||||
return event.locals.user;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user