77 lines
2.7 KiB
TypeScript

import type { RequestHandler } from '@sveltejs/kit';
import { setBeatLeaderSessionFromSetCookieHeaders } from '$lib/server/beatleaderAuth';
/**
* Session-based login mimicking beatleader-website signin with login/password.
* Proxies credentials to BeatLeader and captures Set-Cookie, storing them as a session for server-side authenticated calls.
*
* Supported body formats:
* - application/json: { login: string, password: string, action?: 'login' | 'signup' }
* - multipart/form-data or application/x-www-form-urlencoded with fields: login, password, action
*/
export const POST: RequestHandler = async ({ request, cookies, fetch }) => {
let login = '';
let password = '';
let action = 'login';
const contentType = request.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
const body = (await request.json()) as any;
login = String(body.login ?? '').trim();
password = String(body.password ?? '').trim();
if (body.action) action = String(body.action);
} else {
const form = await request.formData();
login = String(form.get('login') ?? '').trim();
password = String(form.get('password') ?? '').trim();
action = String(form.get('action') ?? 'login');
}
if (!login || !password) {
return new Response(JSON.stringify({ error: 'login and password are required' }), {
status: 400,
headers: { 'content-type': 'application/json' }
});
}
const fd = new FormData();
fd.set('action', action);
fd.set('login', login);
fd.set('password', password);
// Proxy to BeatLeader website login endpoint
const blRes = await fetch('https://api.beatleader.com/signinoculus', {
method: 'POST',
body: fd,
// Do not send our cookies to third-party; we're simply capturing upstream cookies from response
redirect: 'manual'
});
// In website, successful response is empty text; otherwise contains an error message
const text = await blRes.text();
// Capture Set-Cookie headers regardless of body
try {
const setCookieHeaders = (blRes.headers as any).getSetCookie?.() ?? blRes.headers.get('set-cookie')?.split(',') ?? [];
setBeatLeaderSessionFromSetCookieHeaders(cookies, Array.isArray(setCookieHeaders) ? setCookieHeaders : [setCookieHeaders]);
} catch {}
if (!blRes.ok) {
return new Response(JSON.stringify({ error: text || `BeatLeader returned ${blRes.status}` }), {
status: 400,
headers: { 'content-type': 'application/json' }
});
}
if (text && text.length > 0) {
return new Response(JSON.stringify({ error: text }), {
status: 401,
headers: { 'content-type': 'application/json' }
});
}
return new Response(JSON.stringify({ ok: true }), { headers: { 'content-type': 'application/json' } });
};