* docs: prepare Vendoo 1.41.2 git-ignore boundary hotfix * fix: track native source modules with root-anchored runtime ignores
68 lines
4.5 KiB
JavaScript
68 lines
4.5 KiB
JavaScript
import { objectSchema } from '../../kernel/input-schema.mjs';
|
|
import { getAuthService } from './index.mjs';
|
|
|
|
const emailRule = { type: 'string', required: true, minLength: 3, maxLength: 254, pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ };
|
|
|
|
export function registerPublicAuthRoutes({ app, routes, deps }) {
|
|
routes.register(app, {
|
|
id: 'auth.setup-status.read', method: 'GET', path: '/auth/setup-check', owner: 'vendoo.auth', policy: 'auth.public',
|
|
csrf: false, stability: 'stable',
|
|
handler: async (_req, res) => res.json(getAuthService().setupStatus({ mailConfigured: deps.isMailerConfigured(), setupTokenRequired: deps.setupTokenRequired })),
|
|
});
|
|
routes.register(app, {
|
|
id: 'auth.setup.create', method: 'POST', path: '/auth/setup', owner: 'vendoo.auth', policy: 'auth.public', csrf: false, stability: 'stable',
|
|
input: objectSchema({ email: emailRule, name: { type: 'string', maxLength: 120 }, password: { type: 'string', required: true, maxLength: 512, trim: false }, setup_token: { type: 'string', maxLength: 512, trim: false } }),
|
|
handler: async (req, res) => {
|
|
const result = getAuthService().setup({ ...req.validatedBody, setupToken: req.get('x-vendoo-setup-token') || req.validatedBody.setup_token, ip: deps.getClientIp(req), userAgent: req.get('user-agent') || '' });
|
|
deps.setSessionCookies(req, res, result.session, result.csrf);
|
|
res.json({ ok: true, redirect: '/' });
|
|
},
|
|
});
|
|
routes.register(app, {
|
|
id: 'auth.login.create', method: 'POST', path: '/auth/login', owner: 'vendoo.auth', policy: 'auth.public', csrf: false, stability: 'stable',
|
|
input: objectSchema({ email: emailRule, password: { type: 'string', required: true, maxLength: 512, trim: false } }),
|
|
handler: async (req, res) => {
|
|
const result = getAuthService().login({ ...req.validatedBody, ip: deps.getClientIp(req), userAgent: req.get('user-agent') || '' });
|
|
deps.setSessionCookies(req, res, result.session, result.csrf);
|
|
res.json({ ok: true, redirect: '/' });
|
|
},
|
|
});
|
|
routes.register(app, {
|
|
id: 'auth.invite.create', method: 'POST', path: '/auth/invite', owner: 'vendoo.auth', policy: 'auth.authenticated',
|
|
middleware: [deps.requireAuth, deps.csrfProtect], csrf: true, stability: 'stable',
|
|
input: objectSchema({ email: emailRule, name: { type: 'string', maxLength: 120 }, role: { type: 'string', enum: ['admin','manager','editor','publisher','viewer'] } }),
|
|
handler: async (req, res) => {
|
|
const { token } = getAuthService().createInvite({ email: req.validatedBody.email, role: req.validatedBody.role || 'editor', createdBy: req.user.id });
|
|
const result = await deps.sendMagicLink(req.validatedBody.email, token, `${req.protocol}://${req.get('host')}`, 'invite');
|
|
deps.auditLog(req.user.id, req.user.email, 'user.invited', 'user', req.validatedBody.email, `Rolle: ${req.validatedBody.role || 'editor'}`, deps.getClientIp(req));
|
|
res.json({ ok: true, message: 'Einladung gesendet!', consoleFallback: result.consoleFallback || false });
|
|
},
|
|
});
|
|
routes.register(app, {
|
|
id: 'auth.magic.redirect', method: 'GET', path: '/auth/magic', owner: 'vendoo.auth', policy: 'auth.public', csrf: false, stability: 'stable',
|
|
handler: async (req, res) => {
|
|
const token = String(req.query?.token || '');
|
|
if (!token) return res.redirect('/login.html?error=' + encodeURIComponent('Kein Token angegeben'));
|
|
res.redirect(`/login.html?invite=${encodeURIComponent(token)}`);
|
|
},
|
|
});
|
|
routes.register(app, {
|
|
id: 'auth.invite.accept', method: 'POST', path: '/auth/accept-invite', owner: 'vendoo.auth', policy: 'auth.public', csrf: false, stability: 'stable',
|
|
input: objectSchema({ token: { type: 'string', required: true, minLength: 16, maxLength: 512, trim: false }, password: { type: 'string', required: true, maxLength: 512, trim: false }, name: { type: 'string', maxLength: 120 } }),
|
|
handler: async (req, res) => {
|
|
const result = getAuthService().acceptInvite({ ...req.validatedBody, ip: deps.getClientIp(req), userAgent: req.get('user-agent') || '' });
|
|
deps.setSessionCookies(req, res, result.session, result.csrf);
|
|
res.json({ ok: true, redirect: '/' });
|
|
},
|
|
});
|
|
routes.register(app, {
|
|
id: 'auth.logout.create', method: 'POST', path: '/auth/logout', owner: 'vendoo.auth', policy: 'auth.authenticated',
|
|
middleware: [deps.requireAuth, deps.csrfProtect], csrf: true, stability: 'stable',
|
|
handler: async (req, res) => {
|
|
getAuthService().logout({ token: req.cookies?.auth_token, ip: deps.getClientIp(req) });
|
|
deps.clearSessionCookies(res);
|
|
res.json({ ok: true });
|
|
},
|
|
});
|
|
}
|