This commit is contained in:
Maieul BOYER 2025-12-10 16:38:26 +01:00
parent 085de41194
commit eb5e4f25a1
No known key found for this signature in database
24 changed files with 1233 additions and 202 deletions

View file

@ -330,6 +330,20 @@
"/api/auth/guest": {
"post": {
"operationId": "guestLogin",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Default Response",
@ -370,6 +384,32 @@
}
}
},
"400": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"kind",
"msg"
],
"properties": {
"kind": {
"enum": [
"failed"
]
},
"msg": {
"enum": [
"guestLogin.failed.invalid"
]
}
}
}
}
}
},
"500": {
"description": "Default Response",
"content": {

View file

@ -1,39 +1,95 @@
import { FastifyPluginAsync } from 'fastify';
import { Type } from 'typebox';
import { Static, Type } from 'typebox';
import { typeResponse, isNullish, MakeStaticResponse } from '@shared/utils';
export const GuestLoginRes = {
'500': typeResponse('failed', ['guestLogin.failed.generic.unknown', 'guestLogin.failed.generic.error']),
'500': typeResponse('failed', [
'guestLogin.failed.generic.unknown',
'guestLogin.failed.generic.error',
]),
'200': typeResponse('success', 'guestLogin.success', {
token: Type.String({
description: 'JWT that represent a logged in user',
}),
}),
'400': typeResponse('failed', 'guestLogin.failed.invalid'),
};
export type GuestLoginRes = MakeStaticResponse<typeof GuestLoginRes>;
export const GuestLoginReq = Type.Object({
name: Type.Optional(Type.String()),
});
export type GuestLoginReq = Static<typeof GuestLoginReq>;
const getRandomFromList = (list: string[]): string => {
return list[Math.floor(Math.random() * list.length)];
};
const USERNAME_CHECK: RegExp = /^[a-zA-Z_0-9]+$/;
const route: FastifyPluginAsync = async (fastify, _opts): Promise<void> => {
void _opts;
fastify.post<{ Body: null, Reply: GuestLoginRes }>(
fastify.post<{ Body: GuestLoginReq; Reply: GuestLoginRes }>(
'/api/auth/guest',
{ schema: { response: GuestLoginRes, operationId: 'guestLogin' } },
{
schema: {
body: GuestLoginReq,
response: GuestLoginRes,
operationId: 'guestLogin',
},
},
async function(req, res) {
void req;
void res;
try {
console.log('DEBUG ----- guest login backend');
const adjective = getRandomFromList(fastify.words.adjectives);
const noun = getRandomFromList(fastify.words.nouns);
let user_name: string | undefined = req.body?.name;
if (isNullish(user_name)) {
const adjective = getRandomFromList(
fastify.words.adjectives,
);
const noun = getRandomFromList(fastify.words.nouns);
user_name = `${adjective}${noun}`;
}
else {
if (user_name.length < 4 || user_name.length > 26) {
return res.makeResponse(
400,
'failed',
'guestLogin.failed.invalid',
);
}
if (!USERNAME_CHECK.test(user_name)) {
return res.makeResponse(
400,
'failed',
'guestLogin.failed.invalid',
);
}
user_name = `g_${user_name}`;
}
const user = await this.db.createGuestUser(`${adjective} ${noun}`);
const orig = user_name;
let i = 0;
while (
this.db.getUserFromDisplayName(user_name) !== undefined &&
i++ < 5
) {
user_name = `${orig}${Date.now() % 1000}`;
}
if (this.db.getUserFromDisplayName(user_name) !== undefined) {
user_name = `${orig}${Date.now()}`;
}
const user = await this.db.createGuestUser(user_name);
if (isNullish(user)) {
return res.makeResponse(500, 'failed', 'guestLogin.failed.generic.unknown');
return res.makeResponse(
500,
'failed',
'guestLogin.failed.generic.unknown',
);
}
return res.makeResponse(200, 'success', 'guestLogin.success', {
token: this.signJwt('auth', user.id.toString()),
@ -41,7 +97,11 @@ const route: FastifyPluginAsync = async (fastify, _opts): Promise<void> => {
}
catch (e: unknown) {
fastify.log.error(e);
return res.makeResponse(500, 'failed', 'guestLogin.failed.generic.error');
return res.makeResponse(
500,
'failed',
'guestLogin.failed.generic.error',
);
}
},
);

View file

@ -30,9 +30,23 @@ const route: FastifyPluginAsync = async (fastify, _opts): Promise<void> => {
const result = await creq.getCode();
const userinfo = await provider.getUserInfo(result);
let u = this.db.getOauth2User(provider.display_name, userinfo.unique_id);
if (isNullish(u)) {
u = await this.db.createOauth2User(userinfo.name, provider.display_name, userinfo.unique_id);
let user_name = userinfo.name;
const orig = user_name;
let i = 0;
while (
this.db.getUserFromDisplayName(user_name) !== undefined &&
i++ < 100
) {
user_name = `${orig}${Date.now() % 1000}`;
}
if (this.db.getUserFromDisplayName(user_name) !== undefined) {
user_name = `${orig}${Date.now()}`;
}
u = await this.db.createOauth2User(user_name, provider.display_name, userinfo.unique_id);
}
if (isNullish(u)) {
return res.code(500).send('failed to fetch or create user...');

View file

@ -47,7 +47,19 @@ const route: FastifyPluginAsync = async (fastify, _opts): Promise<void> => {
// password is good too !
if (this.db.getUserFromLoginName(name) !== undefined) { return res.makeResponse(400, 'failed', 'signin.failed.username.existing'); }
const u = await this.db.createUser(name, name, password);
let user_name = name;
const orig = user_name;
let i = 0;
while (
this.db.getUserFromDisplayName(user_name) !== undefined &&
i++ < 100
) {
user_name = `${orig}${Date.now() % 1000}`;
}
if (this.db.getUserFromDisplayName(user_name) !== undefined) {
user_name = `${orig}${Date.now()}`;
}
const u = await this.db.createUser(name, user_name, password);
if (isNullish(u)) { return res.makeResponse(500, 'failed', 'signin.failed.generic'); }
// every check has been passed, they are now logged in, using this token to say who they are...