diff --git a/.env.example b/.env.example
index bafbd84..25841b6 100644
--- a/.env.example
+++ b/.env.example
@@ -32,6 +32,8 @@ STORAGE_BUCKET=dev
STORAGE_URL=http://localhost:9000
STORAGE_ACCESS_KEY=user
STORAGE_SECRET_KEY=password
+STORAGE_HOST=localhost
+STORAGE_PORT=9000
# Public
PUBLIC_SITE_NAME=
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/AdelieStack.iml b/.idea/AdelieStack.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/AdelieStack.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/git_toolbox_blame.xml b/.idea/git_toolbox_blame.xml
new file mode 100644
index 0000000..7dc1249
--- /dev/null
+++ b/.idea/git_toolbox_blame.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..639900d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..18cfabd
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..7ddfc9e
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..2af8905
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License Copyright (c) 2024 Bradley Shellnut
+
+Permission is hereby granted,
+free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright notice and this permission notice
+(including the next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 274d0fd..d6f5025 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
-# Sveltekit - Taro Stack
+# Sveltekit - Adelie Stack
-## ❗ Important
-
-If you forked this repository before May 27th, you'll want to view commit `653e2c2`. There was an issue with the Hono context not correctly parsing routes.
+This stack is a cloned and modified version of GitHub user [Rykuno](https://github.com/rykuno)'s [TofeStack](https://github.com/Rykuno/TofuStack).
## ❔ What
@@ -11,7 +9,8 @@ A scalable, testable, extensible, template for Sveltekit.
Sveltekit is awesome, but sometimes you need a bit more capability in the backend than what frameworks like
NextJS & Sveltekit can deliver.
-To remedy this, I've attatched a fully fletched backend to run on the Sveltekit process and forward all API requests to it and paired it with some architectural patterns.
+To remedy this, I've attached a fully fleshed out backend to run on the Sveltekit process and forward all API requests
+to it and paired it with some architectural patterns.
`/api/[...slugs]`
@@ -23,23 +22,29 @@ export const GET: RequestHandler = ({ request }) => app.fetch(request);
export const PUT: RequestHandler = ({ request }) => app.fetch(request);
export const DELETE: RequestHandler = ({ request }) => app.fetch(request);
export const POST: RequestHandler = ({ request }) => app.fetch(request);
+export const fallback: RequestHandler = ({ request }) => app.fetch(request);
```
## Local Setup
1. Make sure Docker is running
2. Copy the `.env.example` file and rename to `.env`
-3. `pnpm install`
-4. `pnpm initialize`(this will start the docker-compose and run the initial database migration.)
-5. `pnpm dev`
+3. Ensure that DB_SEEDING and DB_MIGRATING are set to `true` in the `.env` for this first run.
+4. `pnpm install`
+5. The database extension `citext` is being used to allow for case-insensitive string matching. To install the extension run `CREATE EXTENSION IF NOT EXISTS citext;` or add inside an additional drizzle SQL file for startup to use.
+6. `pnpm initialize` (this will start the docker-compose and run the initial database migration.)
+7. `pnpm dev`
+8. Ensure that DB_SEEDING and DB_MIGRATING are set back to `false` in the `.env` after initial set up.
No additional setup is required, zero api keys, zero services to signup for, zero cost.
## How to Use
-This is **not** supposed to serve as an all batteries included ["production boilerplate"](https://github.com/ixartz/Next-js-Boilerplate) with 200 useless sponsored features that get in your way. Templates that do this are ANYTHING but "production" and "quick start".
+This is **not** supposed to serve as an all batteries included ["production boilerplate"](https://github.com/ixartz/Next-js-Boilerplate) with 200 useless sponsored features that get in your way.
+Templates that do this are ANYTHING but "production" and "quick start".
-This is stack is designed to be library agnostic. The philosophy here is to boostrap the concrete, repetitive, and time consuming tasks that every application will need reguardless of what you're building.
+This is stack is designed to be library agnostic. The philosophy here is to boostrap the concrete, repetitive,
+and time-consuming tasks that every application will need regardless of what you're building.
**So - fork this repo, add your favorite libraries, and build out your own "more opinionated" personal template tailored to you**!
@@ -50,21 +55,23 @@ This is stack is designed to be library agnostic. The philosophy here is to boos
- 🟢 Custom Fetch Wrapper
- 🟢 Deployment Template
- 🟠 Authentication
- - 🟢 Email/Passkey
+ - 🟢 Email / Passkey
+ - 🟢 Username / Email and Password
- 🔴 OAuth
- - 🟢 Email Update/Verifiaction
+ - 🟢 Email Update / Verification
- 🟢 Rate limiter
## Technologies
-I'm mostly unopinionated or what technology or libaries someone uses. Wanna [uwu'ify](https://www.npmjs.com/package/owoifyx) your entire fucking app? Go for it.
+I'm mostly un-opinionated of what technology or libraries someone uses. Wanna [uwu'ify](https://www.npmjs.com/package/owoifyx) your entire app? Go for it.
-That being said, there are some libaries that embody my philosophies of building software more than others,
+That being said, there are some libraries that embody my philosophies of building software more than others,
-- [Lucia](https://lucia-auth.com): Hits the right level of abstraction for me. Hand me the tools to build a secure authentication system and let me implement it to suite my needs
-- [Drizzle](https://orm.drizzle.team/) - Drizzle advertises itself as an ORM but I think its deceptive. Its a query builder with a migration client. Everytime I've used an ORM, I find myself fighting it for sometimes the simplist of use cases. Drizzle just gives you type-safety while querying SQL in a native fashion. Learn SQL, not ORMs.
-- [Hono](https://hono.dev/): Fast, lightweight, and built on **web standards**; meaning it can run anywhere you're Sveltekit app can. It's essentially a better, newer, and ironically more stable Express.JS. This provides us an extreemely good foundation to cleanly build ontop of without having to teardown first. It has a zod adapter for validating DTO's which can be shared with the frontend too.
-- [Sveltekit](https://kit.svelte.dev/): After trying Vue, React, Next, and pretty much every frontend framework in the JS ecosystem, its safe to say I vastly prefer Svelte and its priority of building on **web standards**.
+- [Oslo-project](https://oslojs.dev/): Used for implementing crypto, encoding, hashing, and more in the authentication layer.
+- [ArcticJS](https://arcticjs.dev/): Arctic is a collection of OAuth 2.0 clients for popular providers. It only supports the authorization code grant type and intended to be used server-side.
+- [Drizzle](https://orm.drizzle.team/) - Drizzle advertises itself as an ORM, but I think its deceptive. It's a query builder with a migration client. Everytime I've used an ORM, I find myself fighting it for sometimes the simplest of use cases. Drizzle just gives you type-safety while querying SQL in a native fashion. Learn SQL, not ORMs.
+- [Hono](https://hono.dev/): Fast, lightweight, and built on **web standards**; meaning it can run anywhere you're SvelteKit app can. It's essentially a better, newer, and ironically more stable Express.JS. This provides us a perfect foundation to cleanly build on top of without having to teardown first. It has a zod adapter for validating DTO's which can be shared with the frontend too.
+- [SvelteKit](https://svelte.dev/docs/kit/introduction): After trying Vue, React, Next, and pretty much every frontend framework in the JS ecosystem, it's safe to say I vastly prefer Svelte and its priority of building on **web standards**.
## Architecture
@@ -106,6 +113,6 @@ For example, if you want to group folders by domain(DDD), you simply drag and dr
## Testing
-Testing probably isn't first and foremost when creating an app. Thats fine. You should not be spending time writing tests if your app is mutable.
+Testing probably isn't first and foremost when creating an app. That's fine. You should not be spending time writing tests if your app is mutable.
-BUT, a good stack should be **testable** when the time to solidify a codebase arrives. I created this stack with that pinciple in mind. I've provided a examples of how to write these tests under `authentication.service.test.ts` or `users.service.test.ts`
+BUT, a good stack should be **testable** when the time to solidify a codebase arrives. I created this stack with that principle in mind. I've provided a examples of how to write these tests under `authentication.service.test.ts` or `users.service.test.ts`
diff --git a/drizzle.config.ts b/drizzle.config.ts
index 5ec2892..ea7a64d 100644
--- a/drizzle.config.ts
+++ b/drizzle.config.ts
@@ -1,16 +1,28 @@
-import type { Config } from 'drizzle-kit';
+import { defineConfig } from 'drizzle-kit';
-export default {
- out: './src/lib/server/api/databases/postgres/migrations',
- schema: './src/lib/server/api/databases/postgres/tables/*.table.ts',
+/* ------------------------------- !IMPORTANT ------------------------------- */
+/* ---------------- Before running migrations or generations ---------------- */
+/* ------------------ make sure to build the project first ------------------ */
+/* -------------------------------------------------------------------------- */
+
+export default defineConfig({
+ out: './drizzle',
+ schema: './src/lib/server/api/databases/postgres/drizzle-schema.ts',
breakpoints: false,
strict: true,
+ verbose: true,
dialect: 'postgresql',
+ casing: 'snake_case',
dbCredentials: {
- url: process.env.DATABASE_URL!
+ host: process.env.DATABASE_HOST || 'localhost',
+ port: Number(process.envDATABASE_PORT) || 5432,
+ user: process.envDATABASE_USER,
+ password: process.envDATABASE_PASSWORD,
+ database: process.envDATABASE_DB || 'acme',
+ ssl: process.envDATABASE_HOST !== 'localhost',
},
migrations: {
table: 'migrations',
schema: 'public'
}
-} satisfies Config;
+});
diff --git a/drizzle/0001_icy_xorn.sql b/drizzle/0001_icy_xorn.sql
new file mode 100644
index 0000000..29147e5
--- /dev/null
+++ b/drizzle/0001_icy_xorn.sql
@@ -0,0 +1,66 @@
+CREATE TABLE "credentials" (
+ "id" text PRIMARY KEY NOT NULL,
+ "user_id" text NOT NULL,
+ "type" text DEFAULT 'password' NOT NULL,
+ "secret_data" text NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
+);
+
+CREATE TABLE "roles" (
+ "id" text PRIMARY KEY NOT NULL,
+ "name" text NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "roles_name_unique" UNIQUE("name")
+);
+
+CREATE TABLE "user_roles" (
+ "id" text PRIMARY KEY NOT NULL,
+ "user_id" text NOT NULL,
+ "role_id" text NOT NULL,
+ "primary" boolean DEFAULT false,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
+);
+
+CREATE TABLE "users" (
+ "id" text PRIMARY KEY NOT NULL,
+ "username" text NOT NULL,
+ "email" "citext" NOT NULL,
+ "first_name" text,
+ "last_name" text,
+ "email_verified" boolean DEFAULT false,
+ "mfa_enabled" boolean DEFAULT false NOT NULL,
+ "avatar" text,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "users_username_unique" UNIQUE("username"),
+ CONSTRAINT "users_email_unique" UNIQUE("email")
+);
+
+CREATE TABLE "two_factor" (
+ "id" text PRIMARY KEY NOT NULL,
+ "user_id" text NOT NULL,
+ "secret" text NOT NULL,
+ "enabled" boolean DEFAULT false NOT NULL,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "two_factor_user_id_unique" UNIQUE("user_id")
+);
+
+CREATE TABLE "recovery_codes" (
+ "id" text PRIMARY KEY NOT NULL,
+ "user_id" text NOT NULL,
+ "code" text NOT NULL,
+ "used" boolean DEFAULT false,
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
+ CONSTRAINT "recovery_codes_user_id_unique" UNIQUE("user_id")
+);
+
+ALTER TABLE "credentials" ADD CONSTRAINT "credentials_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
+ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
+ALTER TABLE "user_roles" ADD CONSTRAINT "user_roles_role_id_roles_id_fk" FOREIGN KEY ("role_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;
+ALTER TABLE "two_factor" ADD CONSTRAINT "two_factor_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;
+ALTER TABLE "recovery_codes" ADD CONSTRAINT "recovery_codes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;
\ No newline at end of file
diff --git a/drizzle/db_additional_items.sql b/drizzle/db_additional_items.sql
new file mode 100644
index 0000000..1f9a544
--- /dev/null
+++ b/drizzle/db_additional_items.sql
@@ -0,0 +1 @@
+CREATE EXTENSION IF NOT EXISTS citext;
\ No newline at end of file
diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json
new file mode 100644
index 0000000..f2a9d93
--- /dev/null
+++ b/drizzle/meta/0001_snapshot.json
@@ -0,0 +1,451 @@
+{
+ "id": "c0468a97-4bbc-4734-af21-a5aacbbc1334",
+ "prevId": "00000000-0000-0000-0000-000000000000",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.credentials": {
+ "name": "credentials",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'password'"
+ },
+ "secret_data": {
+ "name": "secret_data",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "credentials_user_id_users_id_fk": {
+ "name": "credentials_user_id_users_id_fk",
+ "tableFrom": "credentials",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.roles": {
+ "name": "roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "roles_name_unique": {
+ "name": "roles_name_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "name"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_roles": {
+ "name": "user_roles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role_id": {
+ "name": "role_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "primary": {
+ "name": "primary",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "user_roles_user_id_users_id_fk": {
+ "name": "user_roles_user_id_users_id_fk",
+ "tableFrom": "user_roles",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_roles_role_id_roles_id_fk": {
+ "name": "user_roles_role_id_roles_id_fk",
+ "tableFrom": "user_roles",
+ "tableTo": "roles",
+ "columnsFrom": [
+ "role_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "citext",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_name": {
+ "name": "first_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_name": {
+ "name": "last_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "mfa_enabled": {
+ "name": "mfa_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "avatar": {
+ "name": "avatar",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "users_username_unique": {
+ "name": "users_username_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "username"
+ ]
+ },
+ "users_email_unique": {
+ "name": "users_email_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "email"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.two_factor": {
+ "name": "two_factor",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret": {
+ "name": "secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "two_factor_user_id_users_id_fk": {
+ "name": "two_factor_user_id_users_id_fk",
+ "tableFrom": "two_factor",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "two_factor_user_id_unique": {
+ "name": "two_factor_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.recovery_codes": {
+ "name": "recovery_codes",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "used": {
+ "name": "used",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "recovery_codes_user_id_users_id_fk": {
+ "name": "recovery_codes_user_id_users_id_fk",
+ "tableFrom": "recovery_codes",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "recovery_codes_user_id_unique": {
+ "name": "recovery_codes_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json
new file mode 100644
index 0000000..ae88b05
--- /dev/null
+++ b/drizzle/meta/_journal.json
@@ -0,0 +1,20 @@
+{
+ "version": "7",
+ "dialect": "postgresql",
+ "entries": [
+ {
+ "idx": 0,
+ "version": "7",
+ "when": 1735856813613,
+ "tag": "db_additional_items",
+ "breakpoints": false
+ },
+ {
+ "idx": 1,
+ "version": "7",
+ "when": 1735858227772,
+ "tag": "0001_icy_xorn",
+ "breakpoints": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index f22a571..1f5bfbc 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
"test:ui": "svelte-kit sync && playwright test --ui",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
- "initialize": "pnpm install && docker compose up --no-recreate -d && pnpm db:migrate && pnpm db:seed",
+ "initialize": "pnpm install && docker compose up --no-recreate -d && pnpm db:generate && pnpm db:migrate && pnpm db:seed",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write .",
"storybook": "storybook dev -p 6006",
@@ -43,7 +43,7 @@
"@sveltejs/kit": "^2.15.1",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@types/cookie": "^1.0.0",
- "@types/node": "^22.10.2",
+ "@types/node": "^22.10.4",
"@types/pg": "^8.11.10",
"@types/pg-pool": "^2.0.6",
"@types/qrcode": "^1.5.5",
@@ -57,7 +57,7 @@
"lucide-svelte": "^0.469.0",
"mode-watcher": "^0.5.0",
"storybook": "^8.4.7",
- "svelte": "^5.16.0",
+ "svelte": "^5.16.1",
"svelte-check": "^4.0.0",
"svelte-meta-tags": "^4.0.4",
"svelte-preprocess": "^6.0.3",
@@ -71,7 +71,7 @@
"tailwindcss-animate": "^1.0.7",
"tsx": "^4.19.2",
"typescript": "^5.0.0",
- "vite": "^6.0.6",
+ "vite": "^6.0.7",
"vitest": "^2.0.4",
"zod": "^3.24.1"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3feb7f7..e022cda 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -19,7 +19,7 @@ importers:
version: 0.4.2(hono@4.6.15)(zod@3.24.1)
'@inlang/paraglide-sveltekit':
specifier: ^0.15.0
- version: 0.15.0(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
+ version: 0.15.0(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
'@internationalized/date':
specifier: ^3.5.5
version: 3.6.0
@@ -155,37 +155,37 @@ importers:
version: 8.4.7(storybook@8.4.7)
'@storybook/addon-svelte-csf':
specifier: ^5.0.0-next.21
- version: 5.0.0-next.21(@storybook/svelte@8.4.7(storybook@8.4.7)(svelte@5.16.0))(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(storybook@8.4.7)(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ version: 5.0.0-next.21(@storybook/svelte@8.4.7(storybook@8.4.7)(svelte@5.16.1))(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(storybook@8.4.7)(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
'@storybook/blocks':
specifier: ^8.4.7
version: 8.4.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7)
'@storybook/svelte':
specifier: ^8.4.7
- version: 8.4.7(storybook@8.4.7)(svelte@5.16.0)
+ version: 8.4.7(storybook@8.4.7)(svelte@5.16.1)
'@storybook/sveltekit':
specifier: ^8.4.7
- version: 8.4.7(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(storybook@8.4.7)(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ version: 8.4.7(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(storybook@8.4.7)(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
'@storybook/test':
specifier: ^8.4.7
version: 8.4.7(storybook@8.4.7)
'@sveltejs/adapter-node':
specifier: ^5.2.9
- version: 5.2.11(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
+ version: 5.2.11(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))
'@sveltejs/enhanced-img':
specifier: ^0.4.4
- version: 0.4.4(rollup@4.29.1)(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ version: 0.4.4(rollup@4.29.1)(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
'@sveltejs/kit':
specifier: ^2.15.1
- version: 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ version: 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
'@sveltejs/vite-plugin-svelte':
specifier: ^5.0.3
- version: 5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ version: 5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
'@types/cookie':
specifier: ^1.0.0
version: 1.0.0
'@types/node':
- specifier: ^22.10.2
- version: 22.10.2
+ specifier: ^22.10.4
+ version: 22.10.4
'@types/pg':
specifier: ^8.11.10
version: 8.11.10
@@ -200,7 +200,7 @@ importers:
version: 10.4.20(postcss@8.4.49)
bits-ui:
specifier: 1.0.0-next.76
- version: 1.0.0-next.76(svelte@5.16.0)
+ version: 1.0.0-next.76(svelte@5.16.1)
bullmq:
specifier: ^5.13.0
version: 5.34.6
@@ -212,40 +212,40 @@ importers:
version: 0.30.1
formsnap:
specifier: ^2.0.0
- version: 2.0.0(svelte@5.16.0)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.0)(typescript@5.7.2))
+ version: 2.0.0(svelte@5.16.1)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.1)(typescript@5.7.2))
lucide-svelte:
specifier: ^0.469.0
- version: 0.469.0(svelte@5.16.0)
+ version: 0.469.0(svelte@5.16.1)
mode-watcher:
specifier: ^0.5.0
- version: 0.5.0(svelte@5.16.0)
+ version: 0.5.0(svelte@5.16.1)
storybook:
specifier: ^8.4.7
version: 8.4.7
svelte:
- specifier: ^5.16.0
- version: 5.16.0
+ specifier: ^5.16.1
+ version: 5.16.1
svelte-check:
specifier: ^4.0.0
- version: 4.1.1(picomatch@4.0.2)(svelte@5.16.0)(typescript@5.7.2)
+ version: 4.1.1(picomatch@4.0.2)(svelte@5.16.1)(typescript@5.7.2)
svelte-meta-tags:
specifier: ^4.0.4
- version: 4.0.4(svelte@5.16.0)(typescript@5.7.2)
+ version: 4.0.4(svelte@5.16.1)(typescript@5.7.2)
svelte-preprocess:
specifier: ^6.0.3
- version: 6.0.3(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(svelte@5.16.0)(typescript@5.7.2)
+ version: 6.0.3(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(svelte@5.16.1)(typescript@5.7.2)
svelte-sequential-preprocessor:
specifier: ^2.0.2
version: 2.0.2
svelte-sonner:
specifier: ^0.3.28
- version: 0.3.28(svelte@5.16.0)
+ version: 0.3.28(svelte@5.16.1)
sveltekit-flash-message:
specifier: ^2.4.4
- version: 2.4.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)
+ version: 2.4.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)
sveltekit-superforms:
specifier: ^2.22.1
- version: 2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.0)(typescript@5.7.2)
+ version: 2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.1)(typescript@5.7.2)
tailwind-merge:
specifier: ^2.6.0
version: 2.6.0
@@ -265,11 +265,11 @@ importers:
specifier: ^5.0.0
version: 5.7.2
vite:
- specifier: ^6.0.6
- version: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ specifier: ^6.0.7
+ version: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
vitest:
specifier: ^2.0.4
- version: 2.1.8(@types/node@22.10.2)
+ version: 2.1.8(@types/node@22.10.4)
zod:
specifier: ^3.24.1
version: 3.24.1
@@ -2280,8 +2280,8 @@ packages:
'@types/mdx@2.0.13':
resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
- '@types/node@22.10.2':
- resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==}
+ '@types/node@22.10.4':
+ resolution: {integrity: sha512-99l6wv4HEzBQhvaU/UGoeBoCK61SCROQaCCGyQSgX2tEQ3rKkNZ2S7CEWnS/4s1LV+8ODdK21UeyR1fHP2mXug==}
'@types/pg-pool@2.0.6':
resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==}
@@ -3350,6 +3350,14 @@ packages:
resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==}
engines: {node: '>= 0.4'}
+ get-intrinsic@1.2.7:
+ resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
get-tsconfig@4.8.1:
resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
@@ -4677,8 +4685,8 @@ packages:
resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==}
engines: {node: '>=16'}
- svelte@5.16.0:
- resolution: {integrity: sha512-Ygqsiac6UogVED2ruKclU+pOeMThxWtp9LG+li7BXeDKC2paVIsRTMkNmcON4Zejerd1s5sZHWx6ZtU85xklVg==}
+ svelte@5.16.1:
+ resolution: {integrity: sha512-FsA1OjAKMAFSDob6j/Tv2ZV9rY4SeqPd1WXQlQkFkePAozSHLp6tbkU9qa1xJ+uTRzMSM2Vx3USdsYZBXd3H3g==}
engines: {node: '>=18'}
sveltedoc-parser@4.2.1:
@@ -4948,8 +4956,8 @@ packages:
terser:
optional: true
- vite@6.0.6:
- resolution: {integrity: sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==}
+ vite@6.0.7:
+ resolution: {integrity: sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
peerDependencies:
@@ -5917,17 +5925,17 @@ snapshots:
- babel-plugin-macros
- debug
- '@inlang/paraglide-sveltekit@0.15.0(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
+ '@inlang/paraglide-sveltekit@0.15.0(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
dependencies:
'@inlang/paraglide-js': 1.11.3
'@inlang/paraglide-vite': 1.3.0
'@lix-js/client': 2.2.1
- '@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
commander: 12.1.0
dedent: 1.5.1
devalue: 4.3.3
magic-string: 0.30.17
- svelte: 5.16.0
+ svelte: 5.16.1
transitivePeerDependencies:
- babel-plugin-macros
- debug
@@ -6560,21 +6568,21 @@ snapshots:
storybook: 8.4.7
ts-dedent: 2.2.0
- '@storybook/addon-svelte-csf@5.0.0-next.21(@storybook/svelte@8.4.7(storybook@8.4.7)(svelte@5.16.0))(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(storybook@8.4.7)(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
+ '@storybook/addon-svelte-csf@5.0.0-next.21(@storybook/svelte@8.4.7(storybook@8.4.7)(svelte@5.16.1))(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(storybook@8.4.7)(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
dependencies:
'@storybook/csf': 0.1.13
'@storybook/docs-tools': 8.4.7(storybook@8.4.7)
'@storybook/node-logger': 8.4.7(storybook@8.4.7)
- '@storybook/svelte': 8.4.7(storybook@8.4.7)(svelte@5.16.0)
+ '@storybook/svelte': 8.4.7(storybook@8.4.7)(svelte@5.16.1)
'@storybook/types': 8.4.7(storybook@8.4.7)
- '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
dedent: 1.5.3
es-toolkit: 1.31.0
esrap: 1.3.2
magic-string: 0.30.17
- svelte: 5.16.0
- svelte-ast-print: 0.4.2(svelte@5.16.0)
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ svelte: 5.16.1
+ svelte-ast-print: 0.4.2(svelte@5.16.1)
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
zimmerframe: 1.1.2
transitivePeerDependencies:
- babel-plugin-macros
@@ -6599,13 +6607,13 @@ snapshots:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- '@storybook/builder-vite@8.4.7(storybook@8.4.7)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
+ '@storybook/builder-vite@8.4.7(storybook@8.4.7)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
dependencies:
'@storybook/csf-plugin': 8.4.7(storybook@8.4.7)
browser-assert: 1.2.1
storybook: 8.4.7
ts-dedent: 2.2.0
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
'@storybook/components@8.4.7(storybook@8.4.7)':
dependencies:
@@ -6673,20 +6681,20 @@ snapshots:
react-dom: 18.3.1(react@18.3.1)
storybook: 8.4.7
- '@storybook/svelte-vite@8.4.7(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(storybook@8.4.7)(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
+ '@storybook/svelte-vite@8.4.7(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(storybook@8.4.7)(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
dependencies:
- '@storybook/builder-vite': 8.4.7(storybook@8.4.7)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
- '@storybook/svelte': 8.4.7(storybook@8.4.7)(svelte@5.16.0)
- '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@storybook/builder-vite': 8.4.7(storybook@8.4.7)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@storybook/svelte': 8.4.7(storybook@8.4.7)(svelte@5.16.1)
+ '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
magic-string: 0.30.17
storybook: 8.4.7
- svelte: 5.16.0
- svelte-preprocess: 5.1.4(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(svelte@5.16.0)(typescript@5.7.2)
- svelte2tsx: 0.7.31(svelte@5.16.0)(typescript@5.7.2)
+ svelte: 5.16.1
+ svelte-preprocess: 5.1.4(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(svelte@5.16.1)(typescript@5.7.2)
+ svelte2tsx: 0.7.31(svelte@5.16.1)(typescript@5.7.2)
sveltedoc-parser: 4.2.1
ts-dedent: 2.2.0
typescript: 5.7.2
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
transitivePeerDependencies:
- '@babel/core'
- coffeescript
@@ -6699,7 +6707,7 @@ snapshots:
- sugarss
- supports-color
- '@storybook/svelte@8.4.7(storybook@8.4.7)(svelte@5.16.0)':
+ '@storybook/svelte@8.4.7(storybook@8.4.7)(svelte@5.16.1)':
dependencies:
'@storybook/components': 8.4.7(storybook@8.4.7)
'@storybook/global': 5.0.0
@@ -6707,22 +6715,22 @@ snapshots:
'@storybook/preview-api': 8.4.7(storybook@8.4.7)
'@storybook/theming': 8.4.7(storybook@8.4.7)
storybook: 8.4.7
- svelte: 5.16.0
+ svelte: 5.16.1
sveltedoc-parser: 4.2.1
ts-dedent: 2.2.0
type-fest: 2.19.0
transitivePeerDependencies:
- supports-color
- '@storybook/sveltekit@8.4.7(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(storybook@8.4.7)(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
+ '@storybook/sveltekit@8.4.7(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(storybook@8.4.7)(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
dependencies:
'@storybook/addon-actions': 8.4.7(storybook@8.4.7)
- '@storybook/builder-vite': 8.4.7(storybook@8.4.7)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
- '@storybook/svelte': 8.4.7(storybook@8.4.7)(svelte@5.16.0)
- '@storybook/svelte-vite': 8.4.7(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(storybook@8.4.7)(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@storybook/builder-vite': 8.4.7(storybook@8.4.7)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@storybook/svelte': 8.4.7(storybook@8.4.7)(svelte@5.16.1)
+ '@storybook/svelte-vite': 8.4.7(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(storybook@8.4.7)(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
storybook: 8.4.7
- svelte: 5.16.0
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ svelte: 5.16.1
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
transitivePeerDependencies:
- '@babel/core'
- '@sveltejs/vite-plugin-svelte'
@@ -6756,29 +6764,29 @@ snapshots:
dependencies:
storybook: 8.4.7
- '@sveltejs/adapter-node@5.2.11(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
+ '@sveltejs/adapter-node@5.2.11(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))':
dependencies:
'@rollup/plugin-commonjs': 28.0.2(rollup@4.29.1)
'@rollup/plugin-json': 6.1.0(rollup@4.29.1)
'@rollup/plugin-node-resolve': 16.0.0(rollup@4.29.1)
- '@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
rollup: 4.29.1
- '@sveltejs/enhanced-img@0.4.4(rollup@4.29.1)(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
+ '@sveltejs/enhanced-img@0.4.4(rollup@4.29.1)(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
dependencies:
magic-string: 0.30.17
sharp: 0.33.5
- svelte: 5.16.0
- svelte-parse-markup: 0.1.5(svelte@5.16.0)
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ svelte: 5.16.1
+ svelte-parse-markup: 0.1.5(svelte@5.16.1)
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
vite-imagetools: 7.0.5(rollup@4.29.1)
zimmerframe: 1.1.2
transitivePeerDependencies:
- rollup
- '@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
+ '@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 5.1.1
@@ -6790,29 +6798,29 @@ snapshots:
sade: 1.8.1
set-cookie-parser: 2.7.1
sirv: 3.0.0
- svelte: 5.16.0
+ svelte: 5.16.1
tiny-glob: 0.2.9
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
- '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
+ '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
debug: 4.4.0
- svelte: 5.16.0
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ svelte: 5.16.1
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
transitivePeerDependencies:
- supports-color
- '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
+ '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))':
dependencies:
- '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
debug: 4.4.0
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.17
- svelte: 5.16.0
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
- vitefu: 1.0.4(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ svelte: 5.16.1
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ vitefu: 1.0.4(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
transitivePeerDependencies:
- supports-color
@@ -6880,13 +6888,13 @@ snapshots:
'@types/jsonwebtoken@9.0.7':
dependencies:
- '@types/node': 22.10.2
+ '@types/node': 22.10.4
'@types/luxon@3.4.2': {}
'@types/mdx@2.0.13': {}
- '@types/node@22.10.2':
+ '@types/node@22.10.4':
dependencies:
undici-types: 6.20.0
@@ -6896,7 +6904,7 @@ snapshots:
'@types/pg@8.11.10':
dependencies:
- '@types/node': 22.10.2
+ '@types/node': 22.10.4
pg-protocol: 1.7.0
pg-types: 4.0.2
@@ -6904,7 +6912,7 @@ snapshots:
'@types/qrcode@1.5.5':
dependencies:
- '@types/node': 22.10.2
+ '@types/node': 22.10.4
'@types/react@19.0.2':
dependencies:
@@ -6965,13 +6973,13 @@ snapshots:
chai: 5.1.2
tinyrainbow: 1.2.0
- '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.2))':
+ '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.4))':
dependencies:
'@vitest/spy': 2.1.8
estree-walker: 3.0.3
magic-string: 0.30.17
optionalDependencies:
- vite: 5.4.11(@types/node@22.10.2)
+ vite: 5.4.11(@types/node@22.10.4)
'@vitest/pretty-format@2.0.5':
dependencies:
@@ -7146,15 +7154,15 @@ snapshots:
binary-extensions@2.3.0: {}
- bits-ui@1.0.0-next.76(svelte@5.16.0):
+ bits-ui@1.0.0-next.76(svelte@5.16.1):
dependencies:
'@floating-ui/core': 1.6.8
'@floating-ui/dom': 1.6.12
'@internationalized/date': 3.6.0
esm-env: 1.2.1
- runed: 0.22.0(svelte@5.16.0)
- svelte: 5.16.0
- svelte-toolbelt: 0.7.0(svelte@5.16.0)
+ runed: 0.22.0(svelte@5.16.1)
+ svelte: 5.16.1
+ svelte-toolbelt: 0.7.0(svelte@5.16.1)
block-stream2@2.1.0:
dependencies:
@@ -7963,11 +7971,11 @@ snapshots:
combined-stream: 1.0.8
mime-types: 2.1.35
- formsnap@2.0.0(svelte@5.16.0)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.0)(typescript@5.7.2)):
+ formsnap@2.0.0(svelte@5.16.1)(sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.1)(typescript@5.7.2)):
dependencies:
- svelte: 5.16.0
- svelte-toolbelt: 0.5.0(svelte@5.16.0)
- sveltekit-superforms: 2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.0)(typescript@5.7.2)
+ svelte: 5.16.1
+ svelte-toolbelt: 0.5.0(svelte@5.16.1)
+ sveltekit-superforms: 2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.1)(typescript@5.7.2)
forwarded@0.2.0: {}
@@ -8000,6 +8008,24 @@ snapshots:
hasown: 2.0.2
math-intrinsics: 1.1.0
+ get-intrinsic@1.2.7:
+ dependencies:
+ call-bind-apply-helpers: 1.0.1
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.2
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.0.0
+
get-tsconfig@4.8.1:
dependencies:
resolve-pkg-maps: 1.0.0
@@ -8330,9 +8356,9 @@ snapshots:
lru-cache@10.4.3: {}
- lucide-svelte@0.469.0(svelte@5.16.0):
+ lucide-svelte@0.469.0(svelte@5.16.1):
dependencies:
- svelte: 5.16.0
+ svelte: 5.16.1
luxon@3.5.0: {}
@@ -8412,9 +8438,9 @@ snapshots:
dependencies:
minimist: 1.2.8
- mode-watcher@0.5.0(svelte@5.16.0):
+ mode-watcher@0.5.0(svelte@5.16.1):
dependencies:
- svelte: 5.16.0
+ svelte: 5.16.1
mri@1.2.0: {}
@@ -8920,15 +8946,15 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
- runed@0.20.0(svelte@5.16.0):
+ runed@0.20.0(svelte@5.16.1):
dependencies:
esm-env: 1.2.1
- svelte: 5.16.0
+ svelte: 5.16.1
- runed@0.22.0(svelte@5.16.0):
+ runed@0.22.0(svelte@5.16.1):
dependencies:
esm-env: 1.2.1
- svelte: 5.16.0
+ svelte: 5.16.1
rusha@0.8.14: {}
@@ -9049,14 +9075,14 @@ snapshots:
dependencies:
call-bound: 1.0.3
es-errors: 1.3.0
- get-intrinsic: 1.2.6
+ get-intrinsic: 1.2.7
object-inspect: 1.13.3
side-channel-weakmap@1.0.2:
dependencies:
call-bound: 1.0.3
es-errors: 1.3.0
- get-intrinsic: 1.2.6
+ get-intrinsic: 1.2.7
object-inspect: 1.13.3
side-channel-map: 1.0.1
@@ -9202,51 +9228,51 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
- svelte-ast-print@0.4.2(svelte@5.16.0):
+ svelte-ast-print@0.4.2(svelte@5.16.1):
dependencies:
esrap: 1.2.2
- svelte: 5.16.0
+ svelte: 5.16.1
zimmerframe: 1.1.2
- svelte-check@4.1.1(picomatch@4.0.2)(svelte@5.16.0)(typescript@5.7.2):
+ svelte-check@4.1.1(picomatch@4.0.2)(svelte@5.16.1)(typescript@5.7.2):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
chokidar: 4.0.3
fdir: 6.4.2(picomatch@4.0.2)
picocolors: 1.1.1
sade: 1.8.1
- svelte: 5.16.0
+ svelte: 5.16.1
typescript: 5.7.2
transitivePeerDependencies:
- picomatch
- svelte-meta-tags@4.0.4(svelte@5.16.0)(typescript@5.7.2):
+ svelte-meta-tags@4.0.4(svelte@5.16.1)(typescript@5.7.2):
dependencies:
schema-dts: 1.1.2(typescript@5.7.2)
- svelte: 5.16.0
+ svelte: 5.16.1
transitivePeerDependencies:
- typescript
- svelte-parse-markup@0.1.5(svelte@5.16.0):
+ svelte-parse-markup@0.1.5(svelte@5.16.1):
dependencies:
- svelte: 5.16.0
+ svelte: 5.16.1
- svelte-preprocess@5.1.4(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(svelte@5.16.0)(typescript@5.7.2):
+ svelte-preprocess@5.1.4(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(svelte@5.16.1)(typescript@5.7.2):
dependencies:
'@types/pug': 2.0.10
detect-indent: 6.1.0
magic-string: 0.30.17
sorcery: 0.11.1
strip-indent: 3.0.0
- svelte: 5.16.0
+ svelte: 5.16.1
optionalDependencies:
postcss: 8.4.49
postcss-load-config: 4.0.2(postcss@8.4.49)
typescript: 5.7.2
- svelte-preprocess@6.0.3(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(svelte@5.16.0)(typescript@5.7.2):
+ svelte-preprocess@6.0.3(postcss-load-config@4.0.2(postcss@8.4.49))(postcss@8.4.49)(svelte@5.16.1)(typescript@5.7.2):
dependencies:
- svelte: 5.16.0
+ svelte: 5.16.1
optionalDependencies:
postcss: 8.4.49
postcss-load-config: 4.0.2(postcss@8.4.49)
@@ -9257,28 +9283,28 @@ snapshots:
svelte: 4.2.19
tslib: 2.7.0
- svelte-sonner@0.3.28(svelte@5.16.0):
+ svelte-sonner@0.3.28(svelte@5.16.1):
dependencies:
- svelte: 5.16.0
+ svelte: 5.16.1
- svelte-toolbelt@0.5.0(svelte@5.16.0):
+ svelte-toolbelt@0.5.0(svelte@5.16.1):
dependencies:
clsx: 2.1.1
style-to-object: 1.0.8
- svelte: 5.16.0
+ svelte: 5.16.1
- svelte-toolbelt@0.7.0(svelte@5.16.0):
+ svelte-toolbelt@0.7.0(svelte@5.16.1):
dependencies:
clsx: 2.1.1
- runed: 0.20.0(svelte@5.16.0)
+ runed: 0.20.0(svelte@5.16.1)
style-to-object: 1.0.8
- svelte: 5.16.0
+ svelte: 5.16.1
- svelte2tsx@0.7.31(svelte@5.16.0)(typescript@5.7.2):
+ svelte2tsx@0.7.31(svelte@5.16.1)(typescript@5.7.2):
dependencies:
dedent-js: 1.0.1
pascal-case: 3.1.2
- svelte: 5.16.0
+ svelte: 5.16.1
typescript: 5.7.2
svelte@4.2.19:
@@ -9298,7 +9324,7 @@ snapshots:
magic-string: 0.30.17
periscopic: 3.1.0
- svelte@5.16.0:
+ svelte@5.16.1:
dependencies:
'@ampproject/remapping': 2.3.0
'@jridgewell/sourcemap-codec': 1.5.0
@@ -9323,17 +9349,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
- sveltekit-flash-message@2.4.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0):
+ sveltekit-flash-message@2.4.4(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1):
dependencies:
- '@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
- svelte: 5.16.0
+ '@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ svelte: 5.16.1
- sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.0)(typescript@5.7.2):
+ sveltekit-superforms@2.22.1(@sveltejs/kit@2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(@types/json-schema@7.0.15)(svelte@5.16.1)(typescript@5.7.2):
dependencies:
- '@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.0)(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
+ '@sveltejs/kit': 2.15.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)))(svelte@5.16.1)(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))
devalue: 5.1.1
memoize-weak: 1.0.2
- svelte: 5.16.0
+ svelte: 5.16.1
ts-deepmerge: 7.0.2
optionalDependencies:
'@exodus/schemasafe': 1.3.0
@@ -9557,13 +9583,13 @@ snapshots:
transitivePeerDependencies:
- rollup
- vite-node@2.1.8(@types/node@22.10.2):
+ vite-node@2.1.8(@types/node@22.10.4):
dependencies:
cac: 6.7.14
debug: 4.4.0
es-module-lexer: 1.6.0
pathe: 1.1.2
- vite: 5.4.11(@types/node@22.10.2)
+ vite: 5.4.11(@types/node@22.10.4)
transitivePeerDependencies:
- '@types/node'
- less
@@ -9575,35 +9601,35 @@ snapshots:
- supports-color
- terser
- vite@5.4.11(@types/node@22.10.2):
+ vite@5.4.11(@types/node@22.10.4):
dependencies:
esbuild: 0.21.5
postcss: 8.4.49
rollup: 4.29.1
optionalDependencies:
- '@types/node': 22.10.2
+ '@types/node': 22.10.4
fsevents: 2.3.3
- vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0):
+ vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0):
dependencies:
esbuild: 0.24.2
postcss: 8.4.49
rollup: 4.29.1
optionalDependencies:
- '@types/node': 22.10.2
+ '@types/node': 22.10.4
fsevents: 2.3.3
jiti: 1.21.7
tsx: 4.19.2
yaml: 2.7.0
- vitefu@1.0.4(vite@6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)):
+ vitefu@1.0.4(vite@6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)):
optionalDependencies:
- vite: 6.0.6(@types/node@22.10.2)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
+ vite: 6.0.7(@types/node@22.10.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)
- vitest@2.1.8(@types/node@22.10.2):
+ vitest@2.1.8(@types/node@22.10.4):
dependencies:
'@vitest/expect': 2.1.8
- '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.2))
+ '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.4))
'@vitest/pretty-format': 2.1.8
'@vitest/runner': 2.1.8
'@vitest/snapshot': 2.1.8
@@ -9619,11 +9645,11 @@ snapshots:
tinyexec: 0.3.2
tinypool: 1.0.2
tinyrainbow: 1.2.0
- vite: 5.4.11(@types/node@22.10.2)
- vite-node: 2.1.8(@types/node@22.10.2)
+ vite: 5.4.11(@types/node@22.10.4)
+ vite-node: 2.1.8(@types/node@22.10.4)
why-is-node-running: 2.3.0
optionalDependencies:
- '@types/node': 22.10.2
+ '@types/node': 22.10.4
transitivePeerDependencies:
- less
- lightningcss
diff --git a/src/app.d.ts b/src/app.d.ts
index 07624ab..cae68e7 100644
--- a/src/app.d.ts
+++ b/src/app.d.ts
@@ -1,7 +1,6 @@
import { ApiClient } from '$lib/server/api';
-import type { User } from 'lucia';
-import { parseApiResponse } from '$lib/utils/api'
-import type { Security } from '$lib/utils/security';
+import type { User } from '$lib/server/api/users/tables/users.table';
+import { parseApiResponse } from '$lib/utils/api';
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
@@ -20,8 +19,6 @@ declare global {
getAuthedUser: () => Promise | null>;
getAuthedUserOrThrow: (redirectTo: string) => Promise>;
}
- // interface PageState {}
- // interface Platform {}
namespace Superforms {
type Message = {
type: 'error' | 'success' | 'info';
diff --git a/src/hooks.server.ts b/src/hooks.server.ts
index 221892c..397c2ac 100644
--- a/src/hooks.server.ts
+++ b/src/hooks.server.ts
@@ -8,6 +8,9 @@ import { i18n } from './lib/i18n';
const handleParaglide: Handle = i18n.handle();
export const app = await startServer();
+// export const init: ServerInit = async () => {
+// await startServer();
+// };
const apiClient: Handle = async ({ event, resolve }) => {
/* ------------------------------ Register api ------------------------------ */
@@ -22,7 +25,8 @@ const apiClient: Handle = async ({ event, resolve }) => {
/* ----------------------------- Auth functions ----------------------------- */
async function getAuthedUser() {
const { data } = await api.users.me.$get().then(parseApiResponse);
- return data?.user;
+ console.log('data', data);
+ return data || null;
}
async function getAuthedUserOrThrow() {
@@ -30,7 +34,7 @@ const apiClient: Handle = async ({ event, resolve }) => {
if (!data || !data.user) {
throw redirect(StatusCodes.TEMPORARY_REDIRECT, '/');
}
- return data?.user;
+ return data || null;
}
/* ------------------------------ Set contexts ------------------------------ */
diff --git a/src/lib/dtos/signin.dto.ts b/src/lib/dtos/signin.dto.ts
index 09cd835..4b58701 100644
--- a/src/lib/dtos/signin.dto.ts
+++ b/src/lib/dtos/signin.dto.ts
@@ -1,7 +1,7 @@
import {z} from "zod";
export const signinDto = z.object({
- username: z
+ identifier: z
.string()
.trim()
.min(3, { message: 'Must be at least 3 characters' })
diff --git a/src/lib/server/api/common/middleware/pino-logger.middleware.ts b/src/lib/server/api/common/middleware/pino-logger.middleware.ts
index 955529d..962f402 100644
--- a/src/lib/server/api/common/middleware/pino-logger.middleware.ts
+++ b/src/lib/server/api/common/middleware/pino-logger.middleware.ts
@@ -12,7 +12,7 @@ export function pinoLogger() {
{
level: configService.envs.LOG_LEVEL || "info",
},
- configService.envs.NODE_ENV === "production" ? undefined : pretty(),
+ configService.envs.NODE_ENV === "production" ? undefined : pretty({ colorize: true }),
),
});
}
diff --git a/src/lib/server/api/common/services/logger.service.ts b/src/lib/server/api/common/services/logger.service.ts
new file mode 100644
index 0000000..8b8cafe
--- /dev/null
+++ b/src/lib/server/api/common/services/logger.service.ts
@@ -0,0 +1,18 @@
+import { inject, injectable } from '@needle-di/core';
+import { ConfigService } from '../../common/configs/config.service';
+import pino from "pino";
+import pretty from "pino-pretty";
+
+@injectable()
+export class LoggerService {
+ public log: pino.Logger;
+
+ constructor(private configService = inject(ConfigService)) {
+ this.log = pino(
+ {
+ level: this.configService.envs.LOG_LEVEL || "info",
+ },
+ this.configService.envs.ENV === 'prod' ? undefined : pretty(),
+ );
+ }
+}
diff --git a/src/lib/server/api/common/services/tokens.service.ts b/src/lib/server/api/common/services/tokens.service.ts
index a478be9..c2debb2 100644
--- a/src/lib/server/api/common/services/tokens.service.ts
+++ b/src/lib/server/api/common/services/tokens.service.ts
@@ -38,7 +38,7 @@ export class TokensService {
return this.hashingService.hash(token);
}
- async verifyHashedToken(hashedToken: string, token: string) {
- return this.hashingService.compare(hashedToken, token);
+ async verifyHashedToken(token: string, hashedToken: string) {
+ return this.hashingService.compare(token, hashedToken);
}
}
diff --git a/src/lib/server/api/controllers/iam.controller.ts b/src/lib/server/api/controllers/iam.controller.ts
deleted file mode 100644
index 4b45dac..0000000
--- a/src/lib/server/api/controllers/iam.controller.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import { setCookie } from 'hono/cookie';
-import { inject, injectable } from 'tsyringe';
-import { zValidator } from '@hono/zod-validator';
-import { limiter } from '../middlewares/rate-limiter.middlware';
-import { requireAuth } from '../middlewares/require-auth.middleware';
-import { Controler } from '../common/types/controller';
-import { updateEmailDto } from '$lib/server/api/dtos/update-email.dto';
-import { verifyEmailDto } from '$lib/server/api/dtos/verify-email.dto';
-import { LuciaService } from '../services/lucia.service';
-import { AuthenticationService } from '../services/authentication.service';
-import { EmailVerificationService } from '../services/email-verification.service';
-import { loginDto } from '../dtos/login.dto';
-import { verifyLoginDto } from '../dtos/verify-login.dto';
-
-@injectable()
-export class IamController extends Controler {
- constructor(
- @inject(AuthenticationService) private authenticationService: AuthenticationService,
- @inject(EmailVerificationService) private emailVerificationService: EmailVerificationService,
- @inject(LuciaService) private luciaService: LuciaService,
- ) {
- super();
- }
-
- routes() {
- return this.controller
- .get('/me', async (c) => {
- const user = c.var.user;
- return c.json({ user: user });
- })
- .post('/login', zValidator('json', loginDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
- const { email } = c.req.valid('json');
- await this.authenticationService.createLoginRequest({ email });
- return c.json({ message: 'Verification email sent' });
- })
- .post('/login/verify', zValidator('json', verifyLoginDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
- const { email, token } = c.req.valid('json');
- const session = await this.authenticationService.verifyLoginRequest({ email, token });
- const sessionCookie = this.luciaService.lucia.createSessionCookie(session.id);
- setCookie(c, sessionCookie.name, sessionCookie.value, {
- path: sessionCookie.attributes.path,
- maxAge: sessionCookie.attributes.maxAge,
- domain: sessionCookie.attributes.domain,
- sameSite: sessionCookie.attributes.sameSite as any,
- secure: sessionCookie.attributes.secure,
- httpOnly: sessionCookie.attributes.httpOnly,
- expires: sessionCookie.attributes.expires
- });
- return c.json({ message: 'ok' });
- })
- .patch('/email', requireAuth, zValidator('json', updateEmailDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
- const json = c.req.valid('json');
- await this.emailVerificationService.create(c.var.user.id, json.email);
- return c.json({ message: 'Verification email sent' });
- })
- // this could also be named to use custom methods, aka /email#verify
- // https://cloud.google.com/apis/design/custom_methods
- .post('/email/verify', requireAuth, zValidator('json', verifyEmailDto), limiter({ limit: 10, minutes: 60 }), async (c) => {
- const json = c.req.valid('json');
- await this.emailVerificationService.verify(c.var.user.id, json.token);
- return c.json({ message: 'Verified and updated' });
- })
- .post('/logout', requireAuth, async (c) => {
- const sessionId = c.var.session.id;
- await this.authenticationService.logout(sessionId);
- const sessionCookie = this.luciaService.lucia.createBlankSessionCookie();
- setCookie(c, sessionCookie.name, sessionCookie.value, {
- path: sessionCookie.attributes.path,
- maxAge: sessionCookie.attributes.maxAge,
- domain: sessionCookie.attributes.domain,
- sameSite: sessionCookie.attributes.sameSite as any,
- secure: sessionCookie.attributes.secure,
- httpOnly: sessionCookie.attributes.httpOnly,
- expires: sessionCookie.attributes.expires
- });
- return c.json({ status: 'success' });
- })
- }
-}
diff --git a/src/lib/server/api/databases/postgres/seeds/users.ts b/src/lib/server/api/databases/postgres/seeds/users.ts
index 7f7ed47..3a1ed33 100644
--- a/src/lib/server/api/databases/postgres/seeds/users.ts
+++ b/src/lib/server/api/databases/postgres/seeds/users.ts
@@ -14,13 +14,15 @@ export default async function seed(db: NodePgDatabase) {
const adminRole = await db.select().from(schema.roles_table).where(eq(schema.roles_table.name, 'admin'));
const userRole = await db.select().from(schema.roles_table).where(eq(schema.roles_table.name, 'user'));
+ const adminUsername = process.env.ADMIN_USERNAME !== undefined && process.env.ADMIN_USERNAME !== ''
+ ? `${process.env.ADMIN_USERNAME}` : 'admin';
const adminUser = await db
.insert(schema.users_table)
.values({
- username: `${process.env.ADMIN_USERNAME}`,
+ username: adminUsername,
email: '',
- first_name: 'Brad',
- last_name: 'S',
+ first_name: 'Admin',
+ last_name: 'Admin',
})
.returning()
.onConflictDoNothing();
diff --git a/src/lib/server/api/dtos/signin.dto.ts b/src/lib/server/api/dtos/signin.dto.ts
index 09cd835..6cbd8d9 100644
--- a/src/lib/server/api/dtos/signin.dto.ts
+++ b/src/lib/server/api/dtos/signin.dto.ts
@@ -1,12 +1,8 @@
-import {z} from "zod";
+import { z } from 'zod';
export const signinDto = z.object({
- username: z
- .string()
- .trim()
- .min(3, { message: 'Must be at least 3 characters' })
- .max(50, { message: 'Must be less than 50 characters' }),
- password: z.string({ required_error: 'Password is required' }).trim(),
+ identifier: z.string().trim().min(3, { message: 'Must be at least 3 characters' }).max(50, { message: 'Must be less than 50 characters' }),
+ password: z.string({ required_error: 'Password is required' }).trim(),
});
-export type signinDto = z.infer;
\ No newline at end of file
+export type SignInDto = z.infer;
diff --git a/src/lib/server/api/iam/iam.controller.ts b/src/lib/server/api/iam/iam.controller.ts
index 4377eb2..699bd14 100644
--- a/src/lib/server/api/iam/iam.controller.ts
+++ b/src/lib/server/api/iam/iam.controller.ts
@@ -10,10 +10,13 @@ import { Controller } from '../common/factories/controllers.factory';
import { loginRequestDto } from './login-requests/dtos/login-request.dto';
import { signInEmail } from './login-requests/routes/login.routes';
import { rateLimit } from '../common/middleware/rate-limit.middleware';
+import { LoggerService } from '../common/services/logger.service';
+import { signinDto } from '../dtos/signin.dto';
@injectable()
export class IamController extends Controller {
constructor(
+ private loggerService = inject(LoggerService),
private loginRequestsService = inject(LoginRequestsService),
private sessionsService = inject(SessionsService),
) {
@@ -22,7 +25,7 @@ export class IamController extends Controller {
routes() {
return this.controller
- .post('/login', openApi(signInEmail), authState('none'), zValidator('json', loginRequestDto), rateLimit({ limit: 3, minutes: 1 }), async (c) => {
+ .post('/login', openApi(signInEmail), authState('none'), zValidator('json', signinDto), rateLimit({ limit: 3, minutes: 1 }), async (c) => {
const session = await this.loginRequestsService.login(c.req.valid('json'));
await this.sessionsService.setSessionCookie(session);
return c.json({ message: 'welcome' });
diff --git a/src/lib/server/api/iam/login-requests/dtos/login-request.dto.ts b/src/lib/server/api/iam/login-requests/dtos/login-request.dto.ts
index 7089a4b..a9d3559 100644
--- a/src/lib/server/api/iam/login-requests/dtos/login-request.dto.ts
+++ b/src/lib/server/api/iam/login-requests/dtos/login-request.dto.ts
@@ -1,7 +1,7 @@
import { z } from 'zod';
export const loginRequestDto = z.object({
- email: z.string().email(),
+ username: z.string().email(),
password: z.string({ required_error: 'Password is required' }),
});
diff --git a/src/lib/server/api/iam/login-requests/login-requests.service.ts b/src/lib/server/api/iam/login-requests/login-requests.service.ts
index b8d4391..6068517 100644
--- a/src/lib/server/api/iam/login-requests/login-requests.service.ts
+++ b/src/lib/server/api/iam/login-requests/login-requests.service.ts
@@ -1,7 +1,7 @@
import { inject, injectable } from '@needle-di/core';
import { TokensService } from '../../common/services/tokens.service';
import { VerificationCodesService } from '../../common/services/verification-codes.service';
-import { BadRequest, NotFound } from '../../common/utils/exceptions';
+import { BadRequest } from '../../common/utils/exceptions';
import { MailerService } from '../../mail/mailer.service';
import { LoginVerificationEmail } from '../../mail/templates/login-verification.template';
import { WelcomeEmail } from '../../mail/templates/welcome.template';
@@ -10,15 +10,16 @@ import { UsersRepository } from '../../users/users.repository';
import { UsersService } from '../../users/users.service';
import { SessionsService } from '../sessions/sessions.service';
import type { CreateLoginRequestDto } from './dtos/create-login-request.dto';
-import type { LoginRequestDto } from './dtos/login-request.dto';
+import type { SignInDto } from '../../dtos/signin.dto';
import type { VerifyLoginRequestDto } from './dtos/verify-login-request.dto';
import { LoginRequestsRepository } from './login-requests.repository';
-import { logger } from 'hono-pino';
+import { LoggerService } from '../../common/services/logger.service';
@injectable()
export class LoginRequestsService {
constructor(
private credentialsRepository = inject(CredentialsRepository),
+ private loggerService = inject(LoggerService),
private loginRequestsRepository = inject(LoginRequestsRepository),
private usersRepository = inject(UsersRepository),
private verificationCodesService = inject(VerificationCodesService),
@@ -28,28 +29,27 @@ export class LoginRequestsService {
private mailer = inject(MailerService),
) {}
- async login({ email, password }: LoginRequestDto) {
- const existingUser = await this.usersRepository.findOneByEmail(email);
+ async login({ identifier, password }: SignInDto) {
+ const existingUser = await this.usersRepository.findOneByEmailOrUsername(identifier);
if (!existingUser) {
+ this.loggerService.log.debug('User not found for identifier', identifier);
throw BadRequest('Invalid credentials');
}
const credential = await this.credentialsRepository.findPasswordCredentialsByUserId(existingUser.id);
if (!credential) {
+ this.loggerService.log.debug('Password credential not found for user', existingUser.id);
throw BadRequest('Invalid credentials');
}
- try {
- if (!(await this.tokensService.verifyHashedToken(credential.secret_data, password))) {
- throw BadRequest('Invalid credentials');
- }
- } catch (error) {
+ if (!(await this.tokensService.verifyHashedToken(password, credential.secret_data))) {
+ this.loggerService.log.debug(`Invalid password for user ${existingUser.id}`);
throw BadRequest('Invalid credentials');
}
- const totpCredentials = await this.credentialsRepository.findTOTPCredentialsByUserId(existingUser.id);
+ // const totpCredentials = await this.credentialsRepository.findTOTPCredentialsByUserId(existingUser.id);
return this.authExistingUser({ userId: existingUser.id });
}
diff --git a/src/lib/server/api/index.ts b/src/lib/server/api/index.ts
index 6389829..4e4ae1b 100644
--- a/src/lib/server/api/index.ts
+++ b/src/lib/server/api/index.ts
@@ -9,6 +9,8 @@ extendZodWithOpenApi(z);
const applicationController = new Container().get(ApplicationController);
const applicationModule = new Container().get(ApplicationModule);
+export const app = applicationModule.app();
+
/* ------------------------------ startServer ------------------------------ */
export function startServer() {
return applicationModule.start();
diff --git a/src/lib/server/api/users/users.repository.ts b/src/lib/server/api/users/users.repository.ts
index 869929b..ac795f4 100644
--- a/src/lib/server/api/users/users.repository.ts
+++ b/src/lib/server/api/users/users.repository.ts
@@ -1,7 +1,7 @@
import { injectable } from '@needle-di/core';
import { takeFirst, takeFirstOrThrow } from '../common/utils/drizzle';
import { users_table } from './tables/users.table';
-import { eq, type InferSelectModel } from 'drizzle-orm';
+import { eq, or, type InferSelectModel } from 'drizzle-orm';
import { NotFound } from '../common/utils/exceptions';
import { DrizzleRepository } from '../common/factories/drizzle-repository.factory';
@@ -20,6 +20,14 @@ export class UsersRepository extends DrizzleRepository {
return db.select().from(users_table).where(eq(users_table.id, id)).then(takeFirst);
}
+ async findOneByEmailOrUsername(identifier: string, db = this.drizzle.db) {
+ return db
+ .select()
+ .from(users_table)
+ .where(or(eq(users_table.email, identifier), eq(users_table.username, identifier)))
+ .then(takeFirst);
+ }
+
async findOneByEmail(email: string, db = this.drizzle.db) {
return db.select().from(users_table).where(eq(users_table.email, email)).then(takeFirst);
}
diff --git a/src/lib/server/api/users/users.service.ts b/src/lib/server/api/users/users.service.ts
index d3e5a96..17bfee3 100644
--- a/src/lib/server/api/users/users.service.ts
+++ b/src/lib/server/api/users/users.service.ts
@@ -102,6 +102,6 @@ export class UsersService {
throw new Error('Password credentials not found');
}
const { password } = data;
- return this.tokenService.verifyHashedToken(credential.secret_data, password);
+ return this.tokenService.verifyHashedToken(password, credential.secret_data);
}
}
diff --git a/src/lib/types.ts b/src/lib/types.ts
deleted file mode 100644
index d06e983..0000000
--- a/src/lib/types.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export type SwapDatesWithStrings = {
- [k in keyof T]: T[k] extends Date | undefined
- ? string
- : T[k] extends object
- ? SwapDatesWithStrings
- : T[k];
-};
-
-export type Returned = {
- [k in keyof T]: T[k] extends Date | undefined
- ? string
- : T[k] extends object
- ? SwapDatesWithStrings
- : T[k];
-};
diff --git a/src/routes/(app)/settings/+layout.svelte b/src/routes/(app)/(protected)/settings/+layout.svelte
similarity index 95%
rename from src/routes/(app)/settings/+layout.svelte
rename to src/routes/(app)/(protected)/settings/+layout.svelte
index 2a8e36d..08c87e7 100644
--- a/src/routes/(app)/settings/+layout.svelte
+++ b/src/routes/(app)/(protected)/settings/+layout.svelte
@@ -1,6 +1,6 @@
diff --git a/src/routes/(app)/settings/+page.svelte b/src/routes/(app)/(protected)/settings/+page.svelte
similarity index 100%
rename from src/routes/(app)/settings/+page.svelte
rename to src/routes/(app)/(protected)/settings/+page.svelte
diff --git a/src/routes/(app)/settings/account/+page.server.ts b/src/routes/(app)/(protected)/settings/account/+page.server.ts
similarity index 95%
rename from src/routes/(app)/settings/account/+page.server.ts
rename to src/routes/(app)/(protected)/settings/account/+page.server.ts
index a8cc726..b57c05f 100644
--- a/src/routes/(app)/settings/account/+page.server.ts
+++ b/src/routes/(app)/(protected)/settings/account/+page.server.ts
@@ -1,6 +1,6 @@
import { zod } from "sveltekit-superforms/adapters";
import { fail, setError, superValidate } from "sveltekit-superforms";
-import { StatusCodes } from "$lib/constants/status-codes.js";
+import { StatusCodes } from "@/constants/status-codes.js";
import { updateEmailFormSchema, verifyEmailFormSchema } from "./schemas.js";
export let load = async (event) => {
diff --git a/src/routes/(app)/settings/account/+page.svelte b/src/routes/(app)/(protected)/settings/account/+page.svelte
similarity index 100%
rename from src/routes/(app)/settings/account/+page.svelte
rename to src/routes/(app)/(protected)/settings/account/+page.svelte
diff --git a/src/routes/(app)/settings/account/schemas.ts b/src/routes/(app)/(protected)/settings/account/schemas.ts
similarity index 100%
rename from src/routes/(app)/settings/account/schemas.ts
rename to src/routes/(app)/(protected)/settings/account/schemas.ts
diff --git a/src/routes/(app)/settings/account/update-email-card.svelte b/src/routes/(app)/(protected)/settings/account/update-email-card.svelte
similarity index 88%
rename from src/routes/(app)/settings/account/update-email-card.svelte
rename to src/routes/(app)/(protected)/settings/account/update-email-card.svelte
index 7e52189..e413046 100644
--- a/src/routes/(app)/settings/account/update-email-card.svelte
+++ b/src/routes/(app)/(protected)/settings/account/update-email-card.svelte
@@ -8,14 +8,14 @@