Fix mail validation

This commit is contained in:
Peaceultime 2025-12-15 18:39:33 +01:00
parent 888adc4743
commit 94645f9dbf
9 changed files with 39 additions and 37 deletions

View File

@ -1,7 +1,6 @@
import { Database } from "bun:sqlite"; import { Database } from "bun:sqlite";
import { BunSQLiteDatabase, drizzle } from "drizzle-orm/bun-sqlite"; import { BunSQLiteDatabase, drizzle } from "drizzle-orm/bun-sqlite";
import * as schema from '../db/schema'; import * as schema from '../db/schema';
import { eq, or, sql } from "drizzle-orm";
let instance: BunSQLiteDatabase<typeof schema> & { let instance: BunSQLiteDatabase<typeof schema> & {
$client: Database; $client: Database;

BIN
db.sqlite

Binary file not shown.

View File

@ -74,7 +74,7 @@ export default defineEventHandler(async (e): Promise<Return> => {
logSession(e, await setUserSession(e, { user: { id: id.id, username: body.data.username, email: body.data.email, state: 0, signin: new Date(), permissions: [], lastTimestamp: new Date() } }) as UserSessionRequired); logSession(e, await setUserSession(e, { user: { id: id.id, username: body.data.username, email: body.data.email, state: 0, signin: new Date(), permissions: [], lastTimestamp: new Date() } }) as UserSessionRequired);
const emailId = Bun.hash('register' + id.id + hash, Date.now()); const emailId = Bun.hash('register' + id.id + hash, Date.now()).toString(10);
const timestamp = Date.now() + 1000 * 60 * 60; const timestamp = Date.now() + 1000 * 60 * 60;
await runTask('validation', { await runTask('validation', {

View File

@ -24,7 +24,7 @@ export default defineEventHandler(async (e) => {
if(result && result.id) if(result && result.id)
{ {
const id = hash('reset' + result.id + result.hash, Date.now()); const id = hash('reset' + result.id + result.hash, Date.now()).toString(10);
const timestamp = Date.now() + 1000 * 60 * 60; const timestamp = Date.now() + 1000 * 60 * 60;
await runTask('validation', { await runTask('validation', {
payload: { payload: {

View File

@ -47,7 +47,7 @@ export default defineEventHandler(async (e) => {
return; return;
} }
const emailId = hash('register' + data.id + data.hash, Date.now()); const emailId = hash('register' + data.id + data.hash, Date.now()).toString(10);
const timestamp = Date.now() + 1000 * 60 * 60; const timestamp = Date.now() + 1000 * 60 * 60;
await runTask('validation', { await runTask('validation', {

View File

@ -1,4 +1,5 @@
import { dom, text } from "#shared/dom.virtual.util"; import { dom, text } from "#shared/dom.virtual.util";
import { format } from "#shared/general.util";
export default function(data: any) export default function(data: any)
{ {

View File

@ -16,6 +16,8 @@ export default defineEventHandler(async (e) => {
if(!query.success) if(!query.success)
throw query.error; throw query.error;
const date = new Date();
if(Bun.hash('1' + query.data.u.toString(), query.data.t).toString() !== query.data.h) if(Bun.hash('1' + query.data.u.toString(), query.data.t).toString() !== query.data.h)
{ {
return createError({ return createError({
@ -23,7 +25,7 @@ export default defineEventHandler(async (e) => {
message: 'Lien incorrect', message: 'Lien incorrect',
}); });
} }
if(Date.now() > query.data.t + (60 * 60 * 1000)) if(date.getTime() > query.data.t + (60 * 60 * 1000))
{ {
return createError({ return createError({
statusCode: 400, statusCode: 400,
@ -34,7 +36,7 @@ export default defineEventHandler(async (e) => {
const db = useDatabase(); const db = useDatabase();
const validate = db.select(getTableColumns(emailValidationTable)).from(emailValidationTable).where(eq(emailValidationTable.id, query.data.i)).get(); const validate = db.select(getTableColumns(emailValidationTable)).from(emailValidationTable).where(eq(emailValidationTable.id, query.data.i)).get();
if(!validate || validate.timestamp <= new Date()) if(!validate || validate.timestamp <= date)
{ {
return createError({ return createError({
statusCode: 400, statusCode: 400,
@ -42,7 +44,7 @@ export default defineEventHandler(async (e) => {
}); });
} }
db.delete(emailValidationTable).where(lte(emailValidationTable.timestamp, new Date())).run(); db.delete(emailValidationTable).where(lte(emailValidationTable.timestamp, date)).run();
const result = db.select({ state: usersTable.state }).from(usersTable).where(eq(usersTable.id, query.data.u)).get(); const result = db.select({ state: usersTable.state }).from(usersTable).where(eq(usersTable.id, query.data.u)).get();
if(result === undefined) if(result === undefined)

View File

@ -14,18 +14,18 @@ export default defineTask({
name: 'validation', name: 'validation',
description: 'Add email ID to DB', description: 'Add email ID to DB',
}, },
run(e) { run({ payload, context }) {
try { try {
if(e.payload.type !== 'validation') if(payload.type !== 'validation')
{ {
throw new Error(`Données inconnues`); throw new Error(`Données inconnues`);
} }
const payload = e.payload as ValidationPayload; const _payload = payload as ValidationPayload;
const db = useDatabase(); const db = useDatabase();
db.delete(emailValidationTable).where(lt(emailValidationTable.timestamp, new Date())).run(); db.delete(emailValidationTable).where(lt(emailValidationTable.timestamp, new Date())).run();
db.insert(emailValidationTable).values({ id: payload.id, timestamp: new Date(payload.timestamp) }).run(); db.insert(emailValidationTable).values({ id: _payload.id, timestamp: new Date(_payload.timestamp) }).run();
return { result: true }; return { result: true };
} }

View File

@ -1,9 +1,9 @@
import type { Ability, Alignment, ArmorConfig, Character, CharacterConfig, CharacterVariables, CompiledCharacter, DamageType, FeatureItem, ItemConfig, ItemState, Level, MainStat, Resistance, SpellConfig, SpellElement, SpellType, TrainingLevel, WeaponConfig, WeaponType } from "~/types/character"; import type { Ability, Alignment, ArmorConfig, Character, CharacterConfig, CharacterVariables, CompiledCharacter, DamageType, FeatureItem, ItemConfig, ItemState, Level, MainStat, Resistance, SpellElement, SpellType, TrainingLevel, WeaponConfig, WeaponType } from "~/types/character";
import { keyof, z } from "zod/v4"; import { z } from "zod/v4";
import characterConfig from '#shared/character-config.json'; import characterConfig from '#shared/character-config.json';
import proses, { preview } from "#shared/proses"; import proses, { preview } from "#shared/proses";
import { button, buttongroup, checkbox, floater, foldable, input, loading, multiselect, numberpicker, select, tabgroup, Toaster, toggle } from "#shared/components.util"; import { button, buttongroup, checkbox, floater, foldable, input, loading, multiselect, numberpicker, select, tabgroup, Toaster, toggle } from "#shared/components.util";
import { div, dom, icon, span, text, type DOMList, type RedrawableHTML } from "#shared/dom.util"; import { div, dom, icon, span, text, reactive, type DOMList, type RedrawableHTML } from "#shared/dom.util";
import { followermenu, fullblocker, tooltip } from "#shared/floating.util"; import { followermenu, fullblocker, tooltip } from "#shared/floating.util";
import { clamp, deepEquals } from "#shared/general.util"; import { clamp, deepEquals } from "#shared/general.util";
import markdown from "#shared/markdown.util"; import markdown from "#shared/markdown.util";
@ -1006,11 +1006,11 @@ class TrainingPicker extends BuilderTab
]), ]),
div("flex justify-center items-center gap-2 my-2 md:text-base text-sm", [ div("flex justify-center items-center gap-2 my-2 md:text-base text-sm", [
dom("span", { text: "Vie" }), dom("span", { text: "Vie" }),
text(this._builder, '{{compiled.health}}'), text(() => this._builder.compiled.health),
]), ]),
div("flex justify-center items-center gap-2 my-2 md:text-base text-sm", [ div("flex justify-center items-center gap-2 my-2 md:text-base text-sm", [
dom("span", { text: "Mana" }), dom("span", { text: "Mana" }),
text(this._builder, '{{compiled.mana}}'), text(() => this._builder.compiled.mana),
]), ]),
button(text('Suivant'), () => this._builder.display(3), 'h-[35px] px-[15px]'), button(text('Suivant'), () => this._builder.display(3), 'h-[35px] px-[15px]'),
]), dom('span') ]), dom('span')
@ -1311,7 +1311,7 @@ export class CharacterSheet
useRequestFetch()(`/api/character/${id}`).then(character => { useRequestFetch()(`/api/character/${id}`).then(character => {
if(character) if(character)
{ {
this.character = new CharacterCompiler(character); this.character = new CharacterCompiler(reactive(character));
if(character.campaign) if(character.campaign)
{ {
@ -1321,7 +1321,7 @@ export class CharacterSheet
useRequestFetch()(`/api/character/${id}`).then(character => { useRequestFetch()(`/api/character/${id}`).then(character => {
if(character) if(character)
{ {
this.character!.character = character; this.character!.character = reactive(character);
this.character!.values; this.character!.values;
'update' in this.container! && this.container!.update!(true); 'update' in this.container! && this.container!.update!(true);
} }
@ -1458,12 +1458,12 @@ export class CharacterSheet
dom("span", { class: "flex flex-row items-center gap-2 text-3xl font-light" }, [ dom("span", { class: "flex flex-row items-center gap-2 text-3xl font-light" }, [
text("PV: "), text("PV: "),
health.readonly, health.readonly,
text(character, `/ {{health}}`), text(() => character.health),
]), ]),
dom("span", { class: "flex flex-row items-center gap-2 text-3xl font-light" }, [ dom("span", { class: "flex flex-row items-center gap-2 text-3xl font-light" }, [
text("Mana: "), text("Mana: "),
mana.readonly, mana.readonly,
text(character, `/ {{mana}}`), text(() => character.mana),
]), ]),
]), ]),
]), ]),
@ -1478,31 +1478,31 @@ export class CharacterSheet
div("flex flex-row justify-center 2xl:gap-4 gap-2 p-4 border-b border-light-35 dark:border-dark-35", [ div("flex flex-row justify-center 2xl:gap-4 gap-2 p-4 border-b border-light-35 dark:border-dark-35", [
div("flex 2xl:gap-4 gap-2 flex-row items-center justify-between", [ div("flex 2xl:gap-4 gap-2 flex-row items-center justify-between", [
div("flex flex-col items-center px-2", [ div("flex flex-col items-center px-2", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `+{{modifier.strength}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => `+${character.modifier.strength}`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Force" }) dom("span", { class: "text-sm 2xl:text-base", text: "Force" })
]), ]),
div("flex flex-col items-center px-2", [ div("flex flex-col items-center px-2", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `+{{modifier.dexterity}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => `+${character.modifier.dexterity}`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Dextérité" }) dom("span", { class: "text-sm 2xl:text-base", text: "Dextérité" })
]), ]),
div("flex flex-col items-center px-2", [ div("flex flex-col items-center px-2", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `+{{modifier.constitution}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => `+${character.modifier.constitution}`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Constitution" }) dom("span", { class: "text-sm 2xl:text-base", text: "Constitution" })
]), ]),
div("flex flex-col items-center px-2", [ div("flex flex-col items-center px-2", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `+{{modifier.intelligence}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => `+${character.modifier.intelligence}`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Intelligence" }) dom("span", { class: "text-sm 2xl:text-base", text: "Intelligence" })
]), ]),
div("flex flex-col items-center px-2", [ div("flex flex-col items-center px-2", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `+{{modifier.curiosity}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => `+${character.modifier.curiosity}`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Curiosité" }) dom("span", { class: "text-sm 2xl:text-base", text: "Curiosité" })
]), ]),
div("flex flex-col items-center px-2", [ div("flex flex-col items-center px-2", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `+{{modifier.charisma}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => `+${character.modifier.charisma}`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Charisme" }) dom("span", { class: "text-sm 2xl:text-base", text: "Charisme" })
]), ]),
div("flex flex-col items-center px-2", [ div("flex flex-col items-center px-2", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `+{{modifier.psyche}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => `+${character.modifier.psyche}`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Psyché" }) dom("span", { class: "text-sm 2xl:text-base", text: "Psyché" })
]) ])
]), ]),
@ -1511,11 +1511,11 @@ export class CharacterSheet
div("flex 2xl:gap-4 gap-2 flex-row items-center justify-between", [ div("flex 2xl:gap-4 gap-2 flex-row items-center justify-between", [
div("flex flex-col px-2 items-center", [ div("flex flex-col px-2 items-center", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `+{{initiative}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => `+${character.initiative}`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Initiative" }) dom("span", { class: "text-sm 2xl:text-base", text: "Initiative" })
]), ]),
div("flex flex-col px-2 items-center", [ div("flex flex-col px-2 items-center", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, () => character.speed === false ? "Aucun déplacement" : `{{speed}} cases`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => character.speed === false ? "Aucun déplacement" : `${character.speed} cases`) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Course" }) dom("span", { class: "text-sm 2xl:text-base", text: "Course" })
]) ])
]), ]),
@ -1525,15 +1525,15 @@ export class CharacterSheet
div("flex 2xl:gap-4 gap-2 flex-row items-center justify-between", [ div("flex 2xl:gap-4 gap-2 flex-row items-center justify-between", [
icon("game-icons:checked-shield", { width: 32, height: 32 }), icon("game-icons:checked-shield", { width: 32, height: 32 }),
div("flex flex-col px-2 items-center", [ div("flex flex-col px-2 items-center", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `{{defense.passive}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => clamp(character.defense.static + character.defense.passiveparry + character.defense.passivedodge, 0, character.defense.hardcap)) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Passive" }) dom("span", { class: "text-sm 2xl:text-base", text: "Passive" })
]), ]),
div("flex flex-col px-2 items-center", [ div("flex flex-col px-2 items-center", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `{{defense.parry}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => clamp(character.defense.static + character.defense.activeparry + character.defense.passivedodge, 0, character.defense.hardcap)) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Blocage" }) dom("span", { class: "text-sm 2xl:text-base", text: "Blocage" })
]), ]),
div("flex flex-col px-2 items-center", [ div("flex flex-col px-2 items-center", [
dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(character, `{{defense.dodge}}`) ]), dom("span", { class: "2xl:text-2xl text-xl font-bold" }, [ text(() => clamp(character.defense.static + character.defense.passiveparry + character.defense.activedodge, 0, character.defense.hardcap)) ]),
dom("span", { class: "text-sm 2xl:text-base", text: "Esquive" }) dom("span", { class: "text-sm 2xl:text-base", text: "Esquive" })
]) ])
]), ]),
@ -1551,7 +1551,7 @@ export class CharacterSheet
Object.keys(character.abilities).map((ability) => Object.keys(character.abilities).map((ability) =>
div("flex flex-row px-1 justify-between items-center", [ div("flex flex-row px-1 justify-between items-center", [
span("text-sm text-light-70 dark:text-dark-70 max-w-20 truncate", abilityTexts[ability as Ability] || ability), span("text-sm text-light-70 dark:text-dark-70 max-w-20 truncate", abilityTexts[ability as Ability] || ability),
span("font-bold text-base text-light-100 dark:text-dark-100", text(character.abilities, `+{{${ability}}}`)), span("font-bold text-base text-light-100 dark:text-dark-100", text(() => `+${character.abilities[ability as Ability] ?? 0}`)),
]) ])
) )
), ),
@ -1583,10 +1583,10 @@ export class CharacterSheet
]) : undefined, ]) : undefined,
div("grid grid-cols-2 gap-x-3 gap-y-1 text-sm", [ div("grid grid-cols-2 gap-x-3 gap-y-1 text-sm", [
div('flex flex-row items-center gap-2', [ text('Précision'), span('font-bold', text(character.spellranks, "{{precision}}")) ]), div('flex flex-row items-center gap-2', [ text('Précision'), span('font-bold', text(() => character.spellranks.precision)) ]),
div('flex flex-row items-center gap-2', [ text('Savoir'), span('font-bold', text(character.spellranks, "{{knowledge}}")) ]), div('flex flex-row items-center gap-2', [ text('Savoir'), span('font-bold', text(() => character.spellranks.knowledge)) ]),
div('flex flex-row items-center gap-2', [ text('Instinct'), span('font-bold', text(character.spellranks, "{{instinct}}")) ]), div('flex flex-row items-center gap-2', [ text('Instinct'), span('font-bold', text(() => character.spellranks.instinct)) ]),
div('flex flex-row items-center gap-2', [ text('Oeuvres'), span('font-bold', text(character.spellranks, "{{arts}}")) ]), div('flex flex-row items-center gap-2', [ text('Oeuvres'), span('font-bold', text(() => character.spellranks.arts)) ]),
]) ])
]) ])
]), ]),