feat: add Clerk Auth #43
2
.env
|
|
@ -1,2 +1,4 @@
|
||||||
VITE_APP_VERSION=1.0.0-alpha
|
VITE_APP_VERSION=1.0.0-alpha
|
||||||
DATABASE_URL="postgres://hestia:test123@localhost:5432/hestia"
|
DATABASE_URL="postgres://hestia:test123@localhost:5432/hestia"
|
||||||
|
PUBLIC_CLERK_PUBLISHABLE_KEY=secret_do_not_commit_or_change_this_create_.env.local_instead
|
||||||
|
CLERK_SECRET_KEY=secret_do_not_commit_or_change_this_create_.env.local_instead
|
||||||
|
|
|
||||||
1
.gitignore
vendored
|
|
@ -12,6 +12,7 @@ node_modules
|
||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
.idea
|
||||||
|
|
|||||||
|
|
||||||
# Vite
|
# Vite
|
||||||
vite.config.js.timestamp-*
|
vite.config.js.timestamp-*
|
||||||
|
|
|
||||||
BIN
bun.lockb
|
|
@ -3,7 +3,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "bun database:up && bun prisma:push && vite dev",
|
"dev": "bun database:up && bun prisma:generate && bun prisma:push && vite dev",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"build-storybook": "storybook build",
|
"build-storybook": "storybook build",
|
||||||
"database:up": "docker compose -p hestia -f devops/docker-compose.dev.yml up -d && docker compose -p hestia -f devops/docker-compose.dev.yml -f devops/docker-compose.wait.yml run --rm wait -c hestia-database:5432",
|
"database:up": "docker compose -p hestia -f devops/docker-compose.dev.yml up -d && docker compose -p hestia -f devops/docker-compose.dev.yml -f devops/docker-compose.wait.yml run --rm wait -c hestia-database:5432",
|
||||||
|
|
@ -62,17 +62,19 @@
|
||||||
"vitest": "^2.0.4"
|
"vitest": "^2.0.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@clerk/clerk-js": "^5.43.4",
|
||||||
|
"@clerk/express": "^1.3.31",
|
||||||
|
"@clerk/themes": "^2.2.3",
|
||||||
"@flaticon/flaticon-uicons": "^3.3.1",
|
"@flaticon/flaticon-uicons": "^3.3.1",
|
||||||
"@inlang/paraglide-sveltekit": "^0.15.0",
|
"@inlang/paraglide-sveltekit": "^0.15.0",
|
||||||
"@lucia-auth/adapter-prisma": "^4.0.1",
|
|
||||||
"@pothos/core": "^4.3.0",
|
"@pothos/core": "^4.3.0",
|
||||||
"@pothos/plugin-prisma": "^4.4.0",
|
"@pothos/plugin-prisma": "^4.4.0",
|
||||||
"@prisma/client": "6.0.1",
|
"@prisma/client": "6.0.1",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.15",
|
||||||
|
"clerk-sveltekit": "https://pkg.pr.new/wobsoriano/clerk-sveltekit@ca15d4e",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"graphql": "^16.9.0",
|
"graphql": "^16.9.0",
|
||||||
"graphql-yoga": "^5.10.4",
|
"graphql-yoga": "^5.10.4",
|
||||||
"lucia": "^3.2.2",
|
|
||||||
"oslo": "^1.2.1",
|
"oslo": "^1.2.1",
|
||||||
"pino": "^9.5.0",
|
"pino": "^9.5.0",
|
||||||
"pino-pretty": "^13.0.0",
|
"pino-pretty": "^13.0.0",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `password` on the `User` table. All the data in the column will be lost.
|
||||||
|
- You are about to drop the `Session` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "Session" DROP CONSTRAINT "Session_userId_fkey";
|
||||||
|
|
||||||
|
-- DropIndex
|
||||||
|
DROP INDEX "User_email_key";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" DROP COLUMN "password";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "Session";
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- Added the required column `clerkId` to the `User` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" ADD COLUMN "clerkId" TEXT NOT NULL;
|
||||||
|
|
@ -15,24 +15,12 @@ datasource db {
|
||||||
}
|
}
|
||||||
|
|
||||||
model User {
|
model User {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
|
clerkId String
|
||||||
|
|
||||||
email String? @unique
|
email String?
|
||||||
name String
|
name String
|
||||||
password String
|
posts Post[]
|
||||||
posts Post[]
|
|
||||||
sessions Session[]
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
|
||||||
}
|
|
||||||
|
|
||||||
model Session {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
|
|
||||||
expiresAt DateTime
|
|
||||||
user User @relation(references: [id], fields: [userId])
|
|
||||||
userId String
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @default(now()) @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt
|
||||||
|
|
|
||||||
7
src/app.d.ts
vendored
|
|
@ -4,8 +4,11 @@ declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
// interface Error {}
|
// interface Error {}
|
||||||
interface Locals {
|
interface Locals {
|
||||||
user: import('lucia').User | null;
|
auth: {
|
||||||
session: import('lucia').Session | null;
|
userId?: string;
|
||||||
|
orgId?: string | null;
|
||||||
|
sessionId?: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// interface PageData {}
|
// interface PageData {}
|
||||||
// interface PageState {}
|
// interface PageState {}
|
||||||
|
|
|
||||||
3
src/hooks.server.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import { withClerkHandler } from 'clerk-sveltekit/server';
|
||||||
|
|
||||||
|
export const handle = withClerkHandler();
|
||||||
|
https://github.com/wobsoriano/clerk-sveltekit?tab=readme-ov-file#configure-the-server-hook
I am using UI components from the lib so no headless I am using UI components from the lib so no headless
Oh the part your linked, I am using a new version of the lib that using the latest API of Clerk so things changed a lot from that ReadMe Oh the part your linked, I am using a new version of the lib that using the latest API of Clerk so things changed a lot from that ReadMe
|
|||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { messages } from '$lib/i18n';
|
import { messages } from '$lib/i18n';
|
||||||
|
import SignOutButton from 'clerk-sveltekit/client/SignOutButton.svelte';
|
||||||
|
|
||||||
let { title, username }: { title: string; username: string } = $props();
|
let { title, username }: { title: string; username: string } = $props();
|
||||||
|
|
||||||
|
|
@ -10,6 +11,7 @@
|
||||||
<h2 class="prose prose-xl">Hestia</h2>
|
<h2 class="prose prose-xl">Hestia</h2>
|
||||||
<h1 class="prose prose-2xl">{title}</h1>
|
<h1 class="prose prose-2xl">{title}</h1>
|
||||||
<p class="prose prose-lg">{message}</p>
|
<p class="prose prose-lg">{message}</p>
|
||||||
|
<SignOutButton />
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,43 @@
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
import { redirect, type ServerLoadEvent } from '@sveltejs/kit';
|
import { redirect, type ServerLoadEvent } from '@sveltejs/kit';
|
||||||
import dayjs from 'dayjs';
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
import { prisma } from '../prisma';
|
import { prisma } from '../prisma';
|
||||||
|
import { createClerkClient } from '@clerk/express';
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
import { CLERK_SECRET_KEY } from '$env/static/private';
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
import { clerkClient } from 'clerk-sveltekit/server';
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
|
||||||
export async function validateSession(event: ServerLoadEvent) {
|
const clerkSessionClient = createClerkClient({
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
const sessionId = event.cookies.get('auth_session');
|
secretKey: CLERK_SECRET_KEY,
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
if (!sessionId) {
|
});
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
redirect(302, '/login');
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
export async function validateSession({ locals }: ServerLoadEvent) {
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
if (!locals.auth.userId) {
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
return redirect(307, '/login');
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
}
|
}
|
||||||
const session = await prisma.session.findUnique({
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
where: { id: sessionId },
|
if (!locals.auth.orgId && locals.auth.sessionId) {
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
include: { user: true },
|
// Sign out the user if they are not associated with an organization
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
await clerkSessionClient.sessions.revokeSession(locals.auth.sessionId);
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
return redirect(307, '/login');
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
}
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
const clerkUser = await clerkClient.users.getUser(locals.auth.userId);
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
let user = await prisma.user.findFirst({
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
where: {
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
clerkId: clerkUser.id,
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
},
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
});
|
});
|
||||||
if (!session || !session.user) {
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
redirect(302, '/login');
|
if (!user) {
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
user = await prisma.user.create({
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
data: {
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
clerkId: clerkUser.id,
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
email: clerkUser.emailAddresses[0].emailAddress,
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
name: clerkUser.fullName ?? 'Ben the Man',
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
},
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
});
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
}
|
}
|
||||||
const expiry = session.expiresAt;
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
if (dayjs(expiry).isBefore(dayjs())) {
|
return {
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
redirect(302, '/login');
|
user: { name: user.name },
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
}
|
};
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
return session;
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
}
|
}
|
||||||
|
|
|
||||||
|
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
??? ???
don't like that 😉 ? don't like that 😉 ?
Why are we using clerk/express? Why are we using clerk/express?
Because clerk is deprecating the nodejs package and is recommending to use this one for backend Because clerk is deprecating the nodejs package and is recommending to use this one for backend
WE ARE PROFESSIONALS HERE MOE WE ARE PROFESSIONALS HERE MOE
I will change it to an empty string, I thought we were fun professionals I will change it to an empty string, I thought we were fun professionals
is the user fullName optional...? I'd rather not default to a magic string is the user fullName optional...? I'd rather not default to a magic string
If there is a situation where name will be empty/undefined consider changing the db schema If there is a situation where name will be empty/undefined consider changing the db schema
|
|||||||
|
|
@ -1,31 +0,0 @@
|
||||||
import { Lucia } from 'lucia';
|
|
||||||
import { PrismaAdapter } from '@lucia-auth/adapter-prisma';
|
|
||||||
import { prisma } from '$lib/server/prisma';
|
|
||||||
|
|
||||||
const adapter = new PrismaAdapter(prisma.session, prisma.user);
|
|
||||||
// expect error (see next section)
|
|
||||||
export const auth = new Lucia(adapter, {
|
|
||||||
sessionCookie: {
|
|
||||||
attributes: {
|
|
||||||
secure: process.env.NODE_ENV === 'production',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
getUserAttributes: (attributes) => {
|
|
||||||
return {
|
|
||||||
email: attributes.email,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
declare module 'lucia' {
|
|
||||||
interface Register {
|
|
||||||
Lucia: typeof Lucia;
|
|
||||||
DatabaseUserAttributes: DatabaseUserAttributes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DatabaseUserAttributes {
|
|
||||||
email: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Auth = typeof auth;
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import ClerkProvider from 'clerk-sveltekit/client/ClerkProvider.svelte';
|
||||||
import { i18n } from '$lib/i18n';
|
import { i18n } from '$lib/i18n';
|
||||||
import { ParaglideJS } from '@inlang/paraglide-sveltekit';
|
import { ParaglideJS } from '@inlang/paraglide-sveltekit';
|
||||||
import '../app.css';
|
import '../app.css';
|
||||||
|
import { PUBLIC_CLERK_PUBLISHABLE_KEY } from '$env/static/public';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
{@render children()}
|
<ClerkProvider publishableKey={PUBLIC_CLERK_PUBLISHABLE_KEY}>
|
||||||
|
{@render children()}
|
||||||
|
</ClerkProvider>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ParaglideJS {i18n}>
|
<ParaglideJS {i18n}>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { validateSession } from '$lib/server/auth';
|
import { validateSession } from '$lib/server/auth';
|
||||||
|
|
||||||
export async function load(event) {
|
export const load = async (event) => validateSession(event);
|
||||||
await validateSession(event);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,3 @@
|
||||||
import { validateSession } from '$lib/server/auth';
|
import { validateSession } from '$lib/server/auth';
|
||||||
|
|
||||||
export async function load(event) {
|
export const load = async (event) => validateSession(event);
|
||||||
const {
|
|
||||||
user: { password: _, ...rest },
|
|
||||||
} = await validateSession(event);
|
|
||||||
return {
|
|
||||||
user: rest,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
import { Navbar } from '$lib/components/Navigation';
|
import { Navbar } from '$lib/components/Navigation';
|
||||||
import type { User } from '@prisma/client';
|
import type { User } from '@prisma/client';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import 'clerk-sveltekit/client';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: Snippet;
|
children: Snippet;
|
||||||
|
|
@ -11,6 +13,32 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
let { children, data }: Props = $props();
|
let { children, data }: Props = $props();
|
||||||
|
|
||||||
|
let clerk;
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
clerk = window.Clerk;
|
||||||
|
|
||||||
|
if (clerk) {
|
||||||
|
if (!clerk.user || clerk.user?.organizationMemberships.length === 0) {
|
||||||
|
console.debug('No organizations found');
|
||||||
|
await clerk.signOut();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Can you explain what this is doing? Can you explain what this is doing?
I will add some comment, it is automatically selecting the first organization that the user is part of, if you don't do that the user get login without an organization I will add some comment, it is automatically selecting the first organization that the user is part of, if you don't do that the user get login without an organization
It would be better to do this check on the server to prevent anything from being leaked to the client side, you can use It would be better to do this check on the server to prevent anything from being leaked to the client side, you can use `+layout.server.ts`. We could throw an error, `403 - User does not belong to a Tenant`
I am already logging out the user on the backend, this is only selecting an org for him I am already logging out the user on the backend, this is only selecting an org for him
Also, modify the error page to contain a signout button, perhaps under certain http codes (like 403) Also, modify the error page to contain a signout button, perhaps under certain http codes (like 403)
|
|||||||
|
try {
|
||||||
|
// Set the active organization to the first one in the list
|
||||||
|
await clerk.setActive({
|
||||||
|
organization: clerk.user?.organizationMemberships[0].organization.id,
|
||||||
|
});
|
||||||
|
console.debug(
|
||||||
|
`Active organization set to ${clerk.user?.organizationMemberships[0].organization.id}`
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error setting active organization:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Navbar title="Svelte" username={data.user.name} />
|
<Navbar title="Svelte" username={data.user.name} />
|
||||||
|
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
import { messages } from '$lib/i18n';
|
|
||||||
import { email_inuse } from '$lib/paraglide/messages';
|
|
||||||
import { logger } from '$lib/server/logger';
|
|
||||||
import { auth } from '$lib/server/lucia.js';
|
|
||||||
import { prisma } from '$lib/server/prisma';
|
|
||||||
import { fail, redirect, type Actions } from '@sveltejs/kit';
|
|
||||||
import { Argon2id } from 'oslo/password';
|
|
||||||
import { string } from 'zod';
|
|
||||||
|
|
||||||
export const actions = {
|
|
||||||
login: async (event) => {
|
|
||||||
const form = await event.request.formData();
|
|
||||||
const email = form.get('email');
|
|
||||||
if (typeof email !== 'string') {
|
|
||||||
return fail(400, { email: { error: messages.email_required() } });
|
|
||||||
}
|
|
||||||
|
|
||||||
const password = form.get('password') as string;
|
|
||||||
if (!password) {
|
|
||||||
return fail(400, { password: { error: messages.password_required() } });
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await prisma.user.findUnique({
|
|
||||||
where: {
|
|
||||||
email: email,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (!user) {
|
|
||||||
logger.error(`User not found! ${email}`);
|
|
||||||
return fail(404, { email: { value: email, error: messages.user_not_found() } });
|
|
||||||
}
|
|
||||||
|
|
||||||
const validPassword = await new Argon2id().verify(user.password, password);
|
|
||||||
if (!validPassword) {
|
|
||||||
return fail(400, {
|
|
||||||
password: { error: messages.password_incorrect() },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const session = await auth.createSession(user.id, []);
|
|
||||||
const sessionCookie = auth.createSessionCookie(session.id);
|
|
||||||
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
|
||||||
path: '/',
|
|
||||||
maxAge: 120,
|
|
||||||
});
|
|
||||||
redirect(302, '/');
|
|
||||||
},
|
|
||||||
|
|
||||||
register: async (event) => {
|
|
||||||
const form = await event.request.formData();
|
|
||||||
if (!form.has('email')) {
|
|
||||||
return fail(400, { email: { error: messages.email_required() } });
|
|
||||||
}
|
|
||||||
const { success, data: email, error } = string().email().safeParse(form.get('email'));
|
|
||||||
if (!success) {
|
|
||||||
logger.error(error);
|
|
||||||
return fail(400, { email: { value: email, error: messages.email_incorrect() } });
|
|
||||||
}
|
|
||||||
|
|
||||||
const password = form.get('password');
|
|
||||||
if (typeof password !== 'string') {
|
|
||||||
return fail(400, { password: { error: messages.password_required() } });
|
|
||||||
}
|
|
||||||
const name = form.get('name');
|
|
||||||
if (typeof name !== 'string') {
|
|
||||||
return fail(400, { name: { error: messages.name_required() } });
|
|
||||||
}
|
|
||||||
|
|
||||||
const usersWithEmail = await prisma.user.count({ where: { email: email } });
|
|
||||||
if (usersWithEmail !== 0) {
|
|
||||||
return fail(409, { email: { value: email, error: email_inuse() } });
|
|
||||||
}
|
|
||||||
|
|
||||||
const hashedPassword = await new Argon2id().hash(password);
|
|
||||||
const user = await prisma.user.create({
|
|
||||||
data: {
|
|
||||||
email: form.get('email') as string,
|
|
||||||
name: form.get('name') as string,
|
|
||||||
password: hashedPassword,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const session = await auth.createSession(user.id.toString(), {});
|
|
||||||
const sessionCookie = auth.createSessionCookie(session.id);
|
|
||||||
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
|
||||||
path: '/',
|
|
||||||
maxAge: 120,
|
|
||||||
});
|
|
||||||
|
|
||||||
redirect(303, '/');
|
|
||||||
},
|
|
||||||
} satisfies Actions;
|
|
||||||
|
|
@ -1,62 +1,23 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Button from '$lib/components/common/Button';
|
|
||||||
import TextInput from '$lib/components/common/TextInput';
|
|
||||||
import Tabs from '$lib/components/Navigation/Tabs';
|
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
import SignIn from 'clerk-sveltekit/client/SignIn.svelte';
|
||||||
let { form } = $props();
|
import { dark } from '@clerk/themes';
|
||||||
|
|
||||||
let tab: 0 | 1 = $state(0);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet userIcon()}
|
|
||||||
<i class="fi fi-br-envelope"></i>
|
|
||||||
{/snippet}
|
|
||||||
|
|
||||||
{#snippet passwordIcon()}
|
|
||||||
<i class="fi fi-br-key"></i>
|
|
||||||
{/snippet}
|
|
||||||
|
|
||||||
{#snippet nameIcon()}
|
|
||||||
<i class="fi fi-rr-user"></i>
|
|
||||||
{/snippet}
|
|
||||||
|
|
||||||
{#snippet alert(message: string)}
|
|
||||||
<div role="alert" class="alert alert-error absolute -top-20" transition:fade>
|
|
||||||
<i class="fi fi-bs-octagon-xmark h-6 w-6 shrink-0"></i>
|
|
||||||
<span>{message}</span>
|
|
||||||
</div>
|
|
||||||
{/snippet}
|
|
||||||
|
|
||||||
{#snippet Form(variant: 'login' | 'register')}
|
|
||||||
<form method="POST" action={`?/${variant}`}>
|
|
||||||
<div class="card-body gap-4">
|
|
||||||
<TextInput start={userIcon} placeholder="Email" name="email" type="email" />
|
|
||||||
<TextInput
|
|
||||||
start={passwordIcon}
|
|
||||||
placeholder="Password"
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
/>
|
|
||||||
{#if variant === 'register'}
|
|
||||||
<TextInput start={nameIcon} placeholder="Name" name="name" fade />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="card-actions px-4">
|
|
||||||
<Button block type="submit" label="Submit" outline />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{/snippet}
|
|
||||||
|
|
||||||
<div class="page" transition:fade>
|
<div class="page" transition:fade>
|
||||||
<div class="card bg-base-200 py-4 shadow-xl">
|
<div>
|
||||||
<div class="card-title">
|
<SignIn
|
||||||
{#if form}
|
appearance={{
|
||||||
{@render alert(Object.values(form)[0].error)}
|
baseTheme: dark,
|
||||||
{/if}
|
variables: {
|
||||||
<Tabs variant="bordered" bind:selected={tab} tabs={['Login', 'Register']} />
|
colorPrimary: '#FFF',
|
||||||
</div>
|
},
|
||||||
{@render Form(tab === 0 ? 'login' : 'register')}
|
elements: {
|
||||||
|
// Remove the sign-up link
|
||||||
|
footerAction: { display: 'none' },
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
10
src/vite-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VITE_CLERK_PUBLISHABLE_KEY: string
|
||||||
|
// more env variables...
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv
|
||||||
|
}
|
||||||
😂