Skip to content

Commit

Permalink
feat: update lucia configuration (#15)
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Einars <contact@dle.dev>
  • Loading branch information
polaroidkidd authored Nov 3, 2023
1 parent 5482178 commit 93e51ef
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 127 deletions.
3 changes: 1 addition & 2 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
### DEV ###
############
# DB
DATABASE_URL="postgres://admin:pass123@localhost:6500/sk-db"
DATABASE_URL="postgres://admin:pass123@localhost:6500/cloudkit-db"
DATA_PROXY="" # Only used in Prod builds

# REDIS
Expand All @@ -14,7 +14,6 @@ IMAGE_API_TOKEN="" # Only used in Prod builds
IMAGE_API="http://localhost:6501/image"
PUBLIC_IMAGE_DELIVERY="http://localhost:6501/image"


IS_CI=false

# prisma seed variables
Expand Down
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
### DEV ###
############
# DB
DATABASE_URL="postgres://admin:pass123@localhost:6500/sk-db"
DATABASE_URL="postgres://admin:pass123@localhost:6500/cloudkit-db"
DATA_PROXY="" # Only used in Prod builds

# REDIS
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[![Pull Request](https://github.com/polaroidkidd/cloudkit/actions/workflows/PR.yml/badge.svg)](https://github.com/polaroidkidd/cloudkit/actions/workflows/PR.yml) [![Merge to Master](https://github.com/polaroidkidd/cloudkit/actions/workflows/MERGE_MASTER.yml/badge.svg)](https://github.com/polaroidkidd/cloudkit/actions/workflows/MERGE_MASTER.yml)

# SvelteKit Cloudflare Template

This is a complete Sveltekit Template designed to help you release you SvelteKit App on Cloudflare Pages using the following services:
Expand Down Expand Up @@ -69,8 +70,8 @@ For example, If I want to generate my prisma schema for local development I woul

Here are some useful scripts

- `pnpm psql:dump` - Dumps the content of the current database into a `sk-db-dump.sql` file. You can mout this as a volume in the `docker-compose.yaml` file in the `psql` section with this path `- ./sk-db-dump.sql:/docker-entrypoint-initdb.d/init.sql` which will initialize the psql container with those contents on start up every time.
- `pnpm psql:restore` - Restores from the latest `sk-db-dump.sql` file, if it exists.
- `pnpm psql:dump` - Dumps the content of the current database into a `cloudkit-db-dump.sql` file. You can mout this as a volume in the `docker-compose.yaml` file in the `psql` section with this path `- ./cloudkit-db-dump.sql:/docker-entrypoint-initdb.d/init.sql` which will initialize the psql container with those contents on start up every time.
- `pnpm psql:restore` - Restores from the latest `cloudkit-db-dump.sql` file, if it exists.
- `pnpm test:e2e:dev` - Runs the sveltekit development server and Playwright in UI mode. This way you can code and verify your tests at the same time.
- `pnpm clean` - Deletes the `./playwright-report`, `./.wrangler` and `./.svelte-kit` folders for a clean slate
- `pnpm prep` - If your docker containers are running, this will generate the prisma schema, push it to the psql container and seed the database
Expand Down
6 changes: 3 additions & 3 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ services:
ports:
- '6379:6379'
command: redis-server --loglevel warning
sk-db:
cloudkit-db:
image: postgres:15
container_name: sk-db
container_name: cloudkit-db
networks:
- sk-net
environment:
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=pass123
- POSTGRES_DB=sk-db
- POSTGRES_DB=cloudkit-db
ports:
- 6500:5432
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"prisma:push:prod": "dotenv -e .env.production -- prisma db push --schema ./prisma/prod.schema.prisma",
"prisma:studio": "dotenv -e .env.development -- prisma studio --schema ./prisma/dev.schema.prisma",
"prisma:studio:prod": "dotenv -e .env.production -- prisma studio --schema ./prisma/prod.schema.prisma",
"psql:dump": "docker exec -i sk-db /bin/bash -c \"PGPASSWORD=pass123 pg_dump --username admin sk-db\" > ./sk-db-dump.sql",
"psql:restore": "docker exec -i sk-db /bin/bash -c \"PGPASSWORD=pass123 psql --username admin sk-db\" < /sk-db-dump.sql",
"psql:dump": "docker exec -i cloudkit-db /bin/bash -c \"PGPASSWORD=pass123 pg_dump --username admin cloudkit-db\" > ./cloudkit-db-dump.sql",
"psql:restore": "docker exec -i cloudkit-db /bin/bash -c \"PGPASSWORD=pass123 psql --username admin cloudkit-db\" < /cloudkit-db-dump.sql",
"psql:seed": "pnpm prisma:gen:dev && dotenv -e .env.development -- node prisma/seed.js",
"psql:seed:prod": "dotenv -e .env.production -- node prisma/seed.js",
"cloudflare:init": "dotenv -e .env.production -- node createCloudflareProject.js"
Expand Down Expand Up @@ -100,4 +100,4 @@
"vitest": "0.34.6",
"wrangler": "^3.15.0"
}
}
}
9 changes: 5 additions & 4 deletions src/lib/components/sections/scripts.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
<div class="flex flex-col gap-3">
<code>pnpm psql:dump</code>
<div>
Dumps the content of the current database into a <code>sk-db-dump.sql</code> file. You can
<code>./sk-db-dump.sql:/docker-entrypoint-initdb.d/init.sql</code> which will initialize the
psql container with those contents on start up every time.
Dumps the content of the current database into a <code>cloudkit-db-dump.sql</code> file.
You can
<code>./cloudkit-db-dump.sql:/docker-entrypoint-initdb.d/init.sql</code> which will initialize
the psql container with those contents on start up every time.
</div>
</div>
</div>
Expand All @@ -28,7 +29,7 @@
<div class="flex flex-col gap-3">
<code>pnpm psql:restore</code>
<div>
Restores from the latest <code>sk-db-dump.sql</code> file, if it exists.
Restores from the latest <code>cloudkit-db-dump.sql</code> file, if it exists.
</div>
</div>
</div>
Expand Down
179 changes: 67 additions & 112 deletions src/lib/server/auth/lucia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,129 +5,84 @@ import { db } from '@lib/server/repository/prismaClient';
import { error, redirect } from '@sveltejs/kit';
import { sveltekit } from 'lucia/middleware';

import { dev } from '$app/environment';
import { REDIS_TOKEN, REDIS_URL } from '$env/static/private';
import { redis, upstash } from '@lucia-auth/adapter-session-redis';
import type { Auth as LuciaAuth, Configuration } from 'lucia';
import { isDev } from '@lib/utils/general';

type ProdAuth = LuciaAuth<
Configuration & {
adapter: {
user: ReturnType<typeof prisma>;
session: ReturnType<typeof upstash>;
};
env: 'DEV' | 'PROD';
middleware: ReturnType<typeof sveltekit>;
getUserAttributes: (data: unknown) => {
firstName: string;
lastName: string;
email: string;
bio: string;
avatarId: string;
createdAt: Date;
updatedAt: Date;
verified: boolean;
};
}
>;

type DevAuth = LuciaAuth<
Configuration & {
adapter: {
user: ReturnType<typeof prisma>;
session: ReturnType<typeof redis>;
};
env: 'DEV' | 'PROD';
middleware: ReturnType<typeof sveltekit>;
getUserAttributes: (data: unknown) => {
firstName: string;
lastName: string;
email: string;
bio: string;
avatarId: string;
createdAt: Date;
updatedAt: Date;
verified: boolean;
};
}
>;
export const eventualAuth: Promise<ProdAuth | DevAuth> = new Promise((resolve) => {
if (dev) {
import('redis').then((Redis) => {
console.info('Using dev redis');
const redisClient = Redis.createClient({
url: REDIS_URL
});
/**
* Returns a Lucia instance with the appropriate adapter and middleware based on the environment.
* If the environment is development, it uses a Redis session adapter with a local Redis instance.
* If the environment is production, it uses a Redis session adapter with an Upstash Redis instance.
*/
async function getConfiguration() {
if (isDev) {
const sessionAdapter = await import('@lucia-auth/adapter-session-redis');
const Redis = await import('redis');
console.info('Using dev redis');
const redisClient = Redis.createClient({
url: REDIS_URL
});

redisClient.connect();
redisClient.on('error', (err) => console.log('Redis Client Error', err));
redisClient.on('ready', () => console.log('Redis Client Ready'));
redisClient.connect();
redisClient.on('error', (err) => console.log('Redis Client Error', err));
redisClient.on('ready', () => console.log('Redis Client Ready'));

const auth = lucia({
adapter: {
user: prisma(db),
session: redis(redisClient)
},
env: dev ? 'DEV' : 'PROD',
middleware: sveltekit(),
getUserAttributes: (data) => {
return {
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
bio: data.bio,
avatarId: data.avatarId,
createdAt: data.createdAt,
updatedAt: data.updatedAt,
verified: data.verified
};
}
});
resolve(auth as DevAuth);
return lucia({
adapter: {
user: prisma(db),
session: sessionAdapter.redis(redisClient)
},
env: isDev ? 'DEV' : 'PROD',
middleware: sveltekit(),
getUserAttributes: (data) => {
return {
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
bio: data.bio,
avatarId: data.avatarId,
createdAt: data.createdAt,
updatedAt: data.updatedAt,
verified: data.verified
};
}
});
} else {
import('@upstash/redis/cloudflare').then((Redis) => {
console.info('Using prod redis');
const auth = lucia({
adapter: {
user: prisma(db),
session: upstash(
new Redis.Redis({
url: REDIS_URL,
token: REDIS_TOKEN
})
)
},
env: dev ? 'DEV' : 'PROD',
middleware: sveltekit(),
getUserAttributes: (data) => {
return {
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
bio: data.bio,
avatarId: data.avatarId,
createdAt: data.createdAt,
updatedAt: data.updatedAt,
verified: data.verified
};
}
});
resolve(auth as ProdAuth);
const sessionAdapter = await import('@lucia-auth/adapter-session-redis');
const Redis = await import('@upstash/redis/cloudflare');
console.info('Using prod redis');
return lucia({
adapter: {
user: prisma(db),
session: sessionAdapter.upstash(
new Redis.Redis({
url: REDIS_URL,
token: REDIS_TOKEN
})
)
},
env: isDev ? 'DEV' : 'PROD',
middleware: sveltekit(),
getUserAttributes: (data) => {
return {
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
bio: data.bio,
avatarId: data.avatarId,
createdAt: data.createdAt,
updatedAt: data.updatedAt,
verified: data.verified
};
}
});
}
});

export const auth = await eventualAuth;

export type AuthType = Awaited<typeof auth>;
}

/**
*
* @param {App.Locals} locals
* @returns User Session
* @throws Unauthorized if user session is expired or doesn't exist
* The instance of Lucia authentication middleware.
*/
export const auth = await getConfiguration();

export async function getUserSession(
locals: App.Locals,
shouldRedirect = true
Expand Down

0 comments on commit 93e51ef

Please sign in to comment.