Files
heygermany-e2e-mrg3zujp/packages/functions/src/wirings/auth.wiring.js
e2e 3bb535efe8
Some checks failed
Main / Setup and Test (push) Has been cancelled
Main / Build Website (push) Has been cancelled
chore: heygermany customer project
2026-07-11 10:35:04 +02:00

164 lines
5.8 KiB
JavaScript

import { betterAuth } from 'better-auth';
import { magicLink } from 'better-auth/plugins';
import { pikkuBetterAuth } from '#pikku/pikku-types.gen.js';
import { UserRoles, UserTypes } from '@heygermany/sdk';
const DEV_BETTER_AUTH_SECRET = 'dev-better-auth-secret-change-me';
const isLocalDomain = (domain) => {
return !domain || domain.includes('localhost') || domain.includes('127.0.0.1');
};
const getOrigin = (domain) => {
if (isLocalDomain(domain)) {
return 'http://localhost:3000';
}
return `https://api.${domain}`;
};
export const auth = pikkuBetterAuth(async ({ kysely, secrets, variables, config, emailService }) => {
const betterAuthSecret = (await variables.get('BETTER_AUTH_SECRET')) ||
await secrets.getSecret('BETTER_AUTH_SECRET').catch(() => DEV_BETTER_AUTH_SECRET);
if (process.env.NODE_ENV === 'production' && betterAuthSecret === DEV_BETTER_AUTH_SECRET) {
throw new Error('BETTER_AUTH_SECRET must be configured in production');
}
return betterAuth({
secret: betterAuthSecret,
baseURL: getOrigin(config.domain),
trustedOrigins: [
'http://localhost:3001',
'http://localhost:3000',
'http://127.0.0.1:3001',
'http://127.0.0.1:3000',
`https://${config.domain}`,
`https://api.${config.domain}`,
'https://*.pikkufabric.dev',
],
advanced: {
database: {
generateId: 'uuid',
},
crossSubDomainCookies: {
enabled: !isLocalDomain(config.domain),
domain: isLocalDomain(config.domain) ? undefined : config.domain,
},
},
database: {
db: kysely,
type: 'sqlite',
},
user: {
modelName: 'authUser',
fields: {
emailVerified: 'emailVerified',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
},
additionalFields: {
role: {
type: 'string',
required: true,
defaultValue: UserRoles.OWNER,
input: true,
},
type: {
type: 'string',
required: true,
defaultValue: UserTypes.CANDIDATE,
input: true,
},
},
},
session: {
modelName: 'authSession',
fields: {
expiresAt: 'expiresAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
ipAddress: 'ipAddress',
userAgent: 'userAgent',
userId: 'userId',
},
},
account: {
modelName: 'authAccount',
fields: {
accountId: 'accountId',
providerId: 'providerId',
userId: 'userId',
accessToken: 'accessToken',
refreshToken: 'refreshToken',
idToken: 'idToken',
accessTokenExpiresAt: 'accessTokenExpiresAt',
refreshTokenExpiresAt: 'refreshTokenExpiresAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
},
},
verification: {
modelName: 'authVerification',
fields: {
expiresAt: 'expiresAt',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
},
},
emailAndPassword: {
enabled: true,
},
emailVerification: {
sendVerificationEmail: async ({ user, url }) => {
await emailService?.send({
to: user.email,
template: {
name: 'candidate-double-opt-in',
locale: 'en',
data: {
firstname: user.name,
verificationLink: url,
},
},
});
},
},
plugins: [
magicLink({
disableSignUp: true,
sendMagicLink: async ({ email: to, token, metadata }) => {
const user = await kysely
.selectFrom('authUser')
.select(['id', 'name'])
.where('email', '=', to)
.executeTakeFirst();
const name = user?.name || to.split('@')[0];
const templateName = getMagicLinkTemplateName(metadata?.template);
const magicLink = buildMagicLink(config.domain, token);
await emailService?.send({
to,
template: {
name: templateName,
locale: 'en',
data: {
firstname: name,
magicLink,
},
},
});
},
}),
],
});
});
const buildMagicLink = (domain, token) => {
const host = isLocalDomain(domain) ? `http://${domain}` : `https://${domain}`;
return `${host}/auth/magic-link?token=${token}&redirect=/jobs/application`;
};
const MAGIC_LINK_TEMPLATE_NAMES = new Set([
'candidate-magic-link',
'candidate-qualified',
'candidate-invalid-documents',
'candidate-process-incomplete',
]);
const getMagicLinkTemplateName = (template) => {
if (typeof template === 'string' && MAGIC_LINK_TEMPLATE_NAMES.has(template)) {
return template;
}
return 'candidate-magic-link';
};
//# sourceMappingURL=auth.wiring.js.map