78 lines
3.0 KiB
TypeScript
78 lines
3.0 KiB
TypeScript
import { customAlphabet } from '@nanoid';
|
|
import { STATUS_CODE, STATUS_TEXT, StatusCode } from '@std/http';
|
|
|
|
import config from '~config';
|
|
|
|
import dbClient from 'db/client.ts';
|
|
|
|
// Using custom alphabet to exclude - and _
|
|
const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
const nanoid = customAlphabet(alphabet, 20);
|
|
|
|
const genericResponse = (status: StatusCode, customText = '') =>
|
|
new Response(customText || STATUS_TEXT[status], { status: status, statusText: STATUS_TEXT[status] });
|
|
|
|
Deno.serve({ port: config.api.port }, async (req) => {
|
|
const urlPath = req.url.split('?')[0] ?? '';
|
|
const path = (urlPath.split('api')[1] ?? '').toLowerCase().trim();
|
|
console.log(urlPath, path);
|
|
|
|
if (req.method === 'GET') {
|
|
// handle all gets
|
|
} else if (req.method === 'POST' && (path === '/enroll' || path === '/enroll/')) {
|
|
const body = await req.json();
|
|
|
|
let readFailure = false;
|
|
const userNameMatches = await dbClient.query('SELECT name FROM users WHERE name = ?', [body.name]).catch(() => {
|
|
readFailure = true;
|
|
});
|
|
if (readFailure) return genericResponse(STATUS_CODE.InternalServerError, "Couldn't read DB.");
|
|
|
|
if (userNameMatches.length === 0) {
|
|
if (body.name.length < 4 || body.name.length > 20) return genericResponse(STATUS_CODE.BadRequest, `Name too ${body.name.length < 4 ? 'short' : 'long'}.`);
|
|
if (body.pin.length < 4 || body.pin.length > 20) return genericResponse(STATUS_CODE.BadRequest, `PIN too ${body.pin.length < 4 ? 'short' : 'long'}.`);
|
|
if (body.email.length > 20) return genericResponse(STATUS_CODE.BadRequest, `Email too long.`);
|
|
|
|
const userId = nanoid();
|
|
|
|
let writeFailure = false;
|
|
await dbClient.execute('INSERT INTO users(id,name,pin,email) values(?,?,?,?)', [userId, body.name, body.pin, body.email]).catch(() => {
|
|
writeFailure = true;
|
|
});
|
|
|
|
if (writeFailure) {
|
|
return genericResponse(STATUS_CODE.InternalServerError, "Couldn't write DB.");
|
|
} else {
|
|
return genericResponse(STATUS_CODE.OK, JSON.stringify({ userId }));
|
|
}
|
|
} else {
|
|
return genericResponse(STATUS_CODE.BadRequest, 'Username Taken.');
|
|
}
|
|
} else {
|
|
const body = await req.json();
|
|
|
|
let readFailure = false;
|
|
const loginMatch = await dbClient.query('SELECT id, email FROM users WHERE name = ? AND pin = ?', [body.name, body.pin]).catch(() => {
|
|
readFailure = true;
|
|
});
|
|
if (readFailure) return genericResponse(STATUS_CODE.InternalServerError, "Couldn't read DB.");
|
|
if (loginMatch.length === 0) return genericResponse(STATUS_CODE.Forbidden, 'Invalid name/PIN combination.');
|
|
const userId = loginMatch[0].userId;
|
|
const email = loginMatch[0].email;
|
|
|
|
switch (req.method) {
|
|
case 'POST':
|
|
if (path === '/auth' || path === '/auth/') {
|
|
return genericResponse(STATUS_CODE.OK, JSON.stringify({ userId, hasEmail: email.length > 0 }));
|
|
}
|
|
break;
|
|
case 'PUT':
|
|
break;
|
|
case 'DELETE':
|
|
break;
|
|
}
|
|
}
|
|
|
|
return genericResponse(STATUS_CODE.NotImplemented);
|
|
});
|