mirror of https://github.com/TZGyn/shortener
add google oauth
parent
feaf0f3be6
commit
0cd7de59a1
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
ALTER TABLE "user" ALTER COLUMN "password" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "user" ADD COLUMN "google_id" varchar(255);
|
||||
@ -0,0 +1,419 @@
|
||||
{
|
||||
"id": "9ba9c83e-b94c-42c5-84c9-010050810026",
|
||||
"prevId": "ac377af2-68ea-4c36-a69c-4cc57a04a523",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.email_verification_token": {
|
||||
"name": "email_verification_token",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.project": {
|
||||
"name": "project",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"uuid": {
|
||||
"name": "uuid",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"qr_background": {
|
||||
"name": "qr_background",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'#ffffff'"
|
||||
},
|
||||
"qr_foreground": {
|
||||
"name": "qr_foreground",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'#000000'"
|
||||
},
|
||||
"domain_status": {
|
||||
"name": "domain_status",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'verified'"
|
||||
},
|
||||
"enable_custom_domain": {
|
||||
"name": "enable_custom_domain",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"custom_ip": {
|
||||
"name": "custom_ip",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"custom_domain_id": {
|
||||
"name": "custom_domain_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"custom_domain": {
|
||||
"name": "custom_domain",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.session": {
|
||||
"name": "session",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.setting": {
|
||||
"name": "setting",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"qr_background": {
|
||||
"name": "qr_background",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"qr_foreground": {
|
||||
"name": "qr_foreground",
|
||||
"type": "varchar(7)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.shortener": {
|
||||
"name": "shortener",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"link": {
|
||||
"name": "link",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"ios": {
|
||||
"name": "ios",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"ios_link": {
|
||||
"name": "ios_link",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"android": {
|
||||
"name": "android",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"android_link": {
|
||||
"name": "android_link",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"code": {
|
||||
"name": "code",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"active": {
|
||||
"name": "active",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
},
|
||||
"project_id": {
|
||||
"name": "project_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"shortener_code_unique": {
|
||||
"name": "shortener_code_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.user": {
|
||||
"name": "user",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"uuid": {
|
||||
"name": "uuid",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"email_verified": {
|
||||
"name": "email_verified",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"password": {
|
||||
"name": "password",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"user_email_unique": {
|
||||
"name": "user_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.visitor": {
|
||||
"name": "visitor",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"shortener_id": {
|
||||
"name": "shortener_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"country_code": {
|
||||
"name": "country_code",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"country": {
|
||||
"name": "country",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"city": {
|
||||
"name": "city",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"device_type": {
|
||||
"name": "device_type",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "''"
|
||||
},
|
||||
"device_vendor": {
|
||||
"name": "device_vendor",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "''"
|
||||
},
|
||||
"os": {
|
||||
"name": "os",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "''"
|
||||
},
|
||||
"browser": {
|
||||
"name": "browser",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "''"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
@ -1,68 +1,69 @@
|
||||
{
|
||||
"name": "link-shortener-svelte",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --plugin-search-dir . --check .",
|
||||
"format": "prettier --write .",
|
||||
"migrate": "bun ./src/lib/db/migrate.ts",
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-node": "^2.0.0",
|
||||
"@sveltejs/kit": "^2.5.5",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||
"@types/pg": "^8.11.6",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"bun-types": "^1.0.11",
|
||||
"drizzle-kit": "^0.23.1",
|
||||
"lucia": "^3.1.1",
|
||||
"postcss": "^8.4.24",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"prettier": "^3.1.0",
|
||||
"prettier-plugin-svelte": "^3.1.0",
|
||||
"prettier-plugin-tailwindcss": "^0.5.7",
|
||||
"svelte": "^4.2.17",
|
||||
"svelte-adapter-bun": "^0.5.1",
|
||||
"svelte-check": "^3.4.3",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.2.8"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@lucia-auth/adapter-drizzle": "^1.0.7",
|
||||
"@prgm/sveltekit-progress-bar": "^2.0.0",
|
||||
"@types/he": "^1.2.3",
|
||||
"apexcharts": "^3.44.0",
|
||||
"bits-ui": "^0.21.13",
|
||||
"clsx": "^2.0.0",
|
||||
"cmdk-sv": "^0.0.13",
|
||||
"drizzle-orm": "^0.32.1",
|
||||
"formsnap": "^1.0.0",
|
||||
"he": "^1.2.0",
|
||||
"lucide-svelte": "^0.418.0",
|
||||
"mode-watcher": "^0.1.2",
|
||||
"nanoid": "^5.0.3",
|
||||
"node-html-parser": "^6.1.12",
|
||||
"oslo": "^1.2.0",
|
||||
"pg": "^8.11.5",
|
||||
"postgres": "^3.4.3",
|
||||
"qr-code-styling": "^1.6.0-rc.1",
|
||||
"resend": "^3.4.0",
|
||||
"svelte-sonner": "^0.3.10",
|
||||
"sveltekit-superforms": "^2.12.2",
|
||||
"tailwind-merge": "^2.0.0",
|
||||
"tailwind-variants": "^0.1.18",
|
||||
"vaul-svelte": "^0.3.1",
|
||||
"zod": "^3.22.4"
|
||||
}
|
||||
"name": "link-shortener-svelte",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --plugin-search-dir . --check .",
|
||||
"format": "prettier --write .",
|
||||
"migrate": "bun ./src/lib/db/migrate.ts",
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-node": "^2.0.0",
|
||||
"@sveltejs/kit": "^2.5.5",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||
"@types/pg": "^8.11.6",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"bun-types": "^1.0.11",
|
||||
"drizzle-kit": "^0.23.1",
|
||||
"lucia": "^3.1.1",
|
||||
"postcss": "^8.4.24",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"prettier": "^3.1.0",
|
||||
"prettier-plugin-svelte": "^3.1.0",
|
||||
"prettier-plugin-tailwindcss": "^0.5.7",
|
||||
"svelte": "^4.2.17",
|
||||
"svelte-adapter-bun": "^0.5.1",
|
||||
"svelte-check": "^3.4.3",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.2.8"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@lucia-auth/adapter-drizzle": "^1.0.7",
|
||||
"@prgm/sveltekit-progress-bar": "^2.0.0",
|
||||
"@types/he": "^1.2.3",
|
||||
"apexcharts": "^3.44.0",
|
||||
"arctic": "^1.9.2",
|
||||
"bits-ui": "^0.21.13",
|
||||
"clsx": "^2.0.0",
|
||||
"cmdk-sv": "^0.0.13",
|
||||
"drizzle-orm": "^0.32.1",
|
||||
"formsnap": "^1.0.0",
|
||||
"he": "^1.2.0",
|
||||
"lucide-svelte": "^0.418.0",
|
||||
"mode-watcher": "^0.1.2",
|
||||
"nanoid": "^5.0.3",
|
||||
"node-html-parser": "^6.1.12",
|
||||
"oslo": "^1.2.0",
|
||||
"pg": "^8.11.5",
|
||||
"postgres": "^3.4.3",
|
||||
"qr-code-styling": "^1.6.0-rc.1",
|
||||
"resend": "^3.4.0",
|
||||
"svelte-sonner": "^0.3.10",
|
||||
"sveltekit-superforms": "^2.12.2",
|
||||
"tailwind-merge": "^2.0.0",
|
||||
"tailwind-variants": "^0.1.18",
|
||||
"vaul-svelte": "^0.3.1",
|
||||
"zod": "^3.22.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
import type { SVGAttributes } from 'svelte/elements'
|
||||
|
||||
type $$Props = SVGAttributes<SVGElement>
|
||||
</script>
|
||||
|
||||
<svg role="img" viewBox="0 0 24 24" {...$$restProps}>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z" />
|
||||
</svg>
|
||||
@ -0,0 +1,36 @@
|
||||
import { google } from '$lib/server/auth'
|
||||
import { generateState, generateCodeVerifier } from 'arctic'
|
||||
import { serializeCookie } from 'oslo/cookie'
|
||||
import { env } from '$env/dynamic/private'
|
||||
import { redirect } from '@sveltejs/kit'
|
||||
|
||||
export const GET = async (event) => {
|
||||
const state = generateState()
|
||||
const codeVerifier = generateCodeVerifier()
|
||||
|
||||
const url = await google.createAuthorizationURL(
|
||||
state,
|
||||
codeVerifier,
|
||||
{
|
||||
scopes: ['email', 'profile'],
|
||||
},
|
||||
)
|
||||
|
||||
event.cookies.set('google_oauth_state', state, {
|
||||
httpOnly: true,
|
||||
secure: env.APP_ENV === 'prod',
|
||||
maxAge: 60 * 10, // 10 minutes
|
||||
path: '/',
|
||||
sameSite: 'lax',
|
||||
})
|
||||
|
||||
event.cookies.set('google_oauth_code_verifier', codeVerifier, {
|
||||
httpOnly: true,
|
||||
secure: env.APP_ENV === 'prod',
|
||||
maxAge: 60 * 10, // 10 minutes
|
||||
path: '/',
|
||||
sameSite: 'lax',
|
||||
})
|
||||
|
||||
return redirect(302, url.toString())
|
||||
}
|
||||
@ -0,0 +1,127 @@
|
||||
import { OAuth2RequestError } from 'arctic'
|
||||
import { google, lucia } from '$lib/server/auth'
|
||||
import { db } from '$lib/db'
|
||||
import { user } from '$lib/db/schema'
|
||||
import { eq } from 'drizzle-orm'
|
||||
|
||||
interface GoogleUser {
|
||||
sub: string // Unique identifier for the user
|
||||
name: string // Full name of the user
|
||||
email: string // Email address of the user
|
||||
}
|
||||
|
||||
export async function GET(event) {
|
||||
const code = event.url.searchParams.get('code')
|
||||
const state = event.url.searchParams.get('state')
|
||||
const codeVerifier = event.cookies.get('google_oauth_code_verifier')
|
||||
const storedState = event.cookies.get('google_oauth_state') ?? null
|
||||
|
||||
if (
|
||||
!code ||
|
||||
!state ||
|
||||
!storedState ||
|
||||
!codeVerifier ||
|
||||
state !== storedState
|
||||
) {
|
||||
return new Response(null, {
|
||||
status: 400,
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
const tokens = await google.validateAuthorizationCode(
|
||||
code,
|
||||
codeVerifier,
|
||||
)
|
||||
const googleUserResponse = await fetch(
|
||||
'https://www.googleapis.com/oauth2/v3/userinfo',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens.accessToken}`,
|
||||
},
|
||||
},
|
||||
)
|
||||
const googleUser: GoogleUser = await googleUserResponse.json()
|
||||
|
||||
const existingGoogleUser = await db.query.user.findFirst({
|
||||
where: (user, { eq }) => eq(user.googleId, googleUser.sub),
|
||||
})
|
||||
|
||||
if (existingGoogleUser) {
|
||||
const session = await lucia.createSession(
|
||||
existingGoogleUser.id,
|
||||
{},
|
||||
)
|
||||
const sessionCookie = lucia.createSessionCookie(session.id)
|
||||
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
||||
path: '.',
|
||||
...sessionCookie.attributes,
|
||||
})
|
||||
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: '/dashboard',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const existingUser = await db.query.user.findFirst({
|
||||
where: (user, { eq }) => eq(user.email, googleUser.email),
|
||||
})
|
||||
|
||||
if (existingUser) {
|
||||
const updateUser = await db
|
||||
.update(user)
|
||||
.set({
|
||||
email_verified: true,
|
||||
password: null,
|
||||
username: googleUser.name,
|
||||
})
|
||||
.where(eq(user.id, existingUser.id))
|
||||
.returning()
|
||||
|
||||
const newUser = updateUser[0]
|
||||
|
||||
const session = await lucia.createSession(newUser.id, {})
|
||||
const sessionCookie = lucia.createSessionCookie(session.id)
|
||||
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
||||
path: '.',
|
||||
...sessionCookie.attributes,
|
||||
})
|
||||
} else {
|
||||
const insertUser = await db
|
||||
.insert(user)
|
||||
.values({
|
||||
email: googleUser.email, // Using email as username
|
||||
email_verified: true,
|
||||
googleId: googleUser.sub,
|
||||
username: googleUser.name, // Name field may not always be present, handle accordingly
|
||||
})
|
||||
.returning()
|
||||
|
||||
const newUser = insertUser[0]
|
||||
|
||||
const session = await lucia.createSession(newUser.id, {})
|
||||
const sessionCookie = lucia.createSessionCookie(session.id)
|
||||
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
||||
path: '.',
|
||||
...sessionCookie.attributes,
|
||||
})
|
||||
}
|
||||
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: '/dashboard',
|
||||
},
|
||||
})
|
||||
} catch (e) {
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: '/login',
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue