diff --git a/src/hooks.ts b/src/hooks.ts index d74aa83a0..7bb2d8060 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -16,22 +16,24 @@ export const handle = handleSession( async function ({ event, resolve }) { let response; try { - let gitlabToken = event.locals.cookies.gitlabToken; - let ghToken = event.locals.cookies.ghToken; - if (event.locals.cookies['kit.session']) { - const { permission, teamId, userId } = await getUserDetails(event, false); - const newSession = { - userId, - teamId, - permission, - isAdmin: permission === 'admin' || permission === 'owner', - expires: event.locals.session.data.expires, - gitlabToken, - ghToken - }; + if (event.locals.cookies) { + let gitlabToken = event.locals.cookies.gitlabToken || null; + let ghToken = event.locals.cookies.ghToken; + if (event.locals.cookies['kit.session']) { + const { permission, teamId, userId } = await getUserDetails(event, false); + const newSession = { + userId, + teamId, + permission, + isAdmin: permission === 'admin' || permission === 'owner', + expires: event.locals.session.data.expires, + gitlabToken, + ghToken + }; - if (JSON.stringify(event.locals.session.data) !== JSON.stringify(newSession)) { - event.locals.session.data = { ...newSession }; + if (JSON.stringify(event.locals.session.data) !== JSON.stringify(newSession)) { + event.locals.session.data = { ...newSession }; + } } } diff --git a/src/lib/components/CopyPasswordField.svelte b/src/lib/components/CopyPasswordField.svelte index ab43f48bd..ac2ba94d4 100644 --- a/src/lib/components/CopyPasswordField.svelte +++ b/src/lib/components/CopyPasswordField.svelte @@ -29,7 +29,7 @@ } - showActions(true)} on:mouseleave={() => showActions(false)} @@ -78,7 +78,7 @@ {/if} {#if actionsShow} -
+
{#if isPasswordField}
(showPassword = !showPassword)}> @@ -142,4 +142,4 @@
{/if} - +
diff --git a/src/lib/components/Loading.svelte b/src/lib/components/Loading.svelte index de113e261..99a1054ea 100644 --- a/src/lib/components/Loading.svelte +++ b/src/lib/components/Loading.svelte @@ -11,7 +11,7 @@
{:else} -
+
{/if} diff --git a/src/lib/database/users.ts b/src/lib/database/users.ts index e8d3f8ba6..9c09d0aaf 100644 --- a/src/lib/database/users.ts +++ b/src/lib/database/users.ts @@ -6,16 +6,17 @@ import { asyncExecShell, uniqueName } from '$lib/common'; import * as db from '$lib/database'; import { startCoolifyProxy } from '$lib/haproxy'; - -export async function login({ email, password }) { +export async function hashPassword(password: string) { const saltRounds = 15; + return bcrypt.hash(password, saltRounds); +} +export async function login({ email, password }) { const users = await prisma.user.count(); const userFound = await prisma.user.findUnique({ where: { email }, include: { teams: true, permission: true }, rejectOnNotFound: false }); - console.log(userFound); // Registration disabled if database is not seeded properly const { isRegistrationEnabled, id } = await db.listSettings(); @@ -64,7 +65,7 @@ export async function login({ email, password }) { }; } - const hashedPassword = await bcrypt.hash(password, saltRounds); + const hashedPassword = await hashPassword(password); if (users === 0) { permission = 'owner'; isAdmin = true; diff --git a/src/lib/settings.ts b/src/lib/settings.ts index d9e7cff2c..79742e434 100644 --- a/src/lib/settings.ts +++ b/src/lib/settings.ts @@ -1,5 +1,7 @@ export const publicPaths = [ '/login', + '/reset', + '/reset/password', '/webhooks/success', '/webhooks/github', '/webhooks/github/install', diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte index 75265e1b0..04310b8b3 100644 --- a/src/routes/__layout.svelte +++ b/src/routes/__layout.svelte @@ -2,7 +2,7 @@ import type { Load } from '@sveltejs/kit'; import { publicPaths } from '$lib/settings'; - export const load: Load = async ({ fetch, url, params, session }) => { + export const load: Load = async ({ fetch, url, session }) => { if (!session.userId && !publicPaths.includes(url.pathname)) { return { status: 302, diff --git a/src/routes/login/index.svelte b/src/routes/login/index.svelte index 131639d53..b1a538c82 100644 --- a/src/routes/login/index.svelte +++ b/src/routes/login/index.svelte @@ -67,6 +67,7 @@ class:text-stone-600={loading} class:bg-coollabs={!loading}>{loading ? 'Authenticating...' : 'Login'} +
diff --git a/src/routes/reset/index.json.ts b/src/routes/reset/index.json.ts new file mode 100644 index 000000000..a75ea4766 --- /dev/null +++ b/src/routes/reset/index.json.ts @@ -0,0 +1,26 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import * as db from '$lib/database'; + +export const get: RequestHandler = async () => { + const users = await db.prisma.user.findMany({}); + return { + status: 200, + body: { + users + } + }; +}; +export const post: RequestHandler = async (event) => { + const { secretKey } = await event.request.json(); + if (secretKey !== process.env.COOLIFY_SECRET_KEY) { + return { + status: 500, + body: { + error: 'Invalid secret key.' + } + }; + } + return { + status: 200 + }; +}; diff --git a/src/routes/reset/index.svelte b/src/routes/reset/index.svelte new file mode 100644 index 000000000..498c63e64 --- /dev/null +++ b/src/routes/reset/index.svelte @@ -0,0 +1,96 @@ + + +
goto('/')}> + + + + + + +
+
Reset Password
+
+ {#if password} + + + + + + + + + {#each users as user} + + + + + {/each} + +
EmailNew password
{user.email} + +
+ {:else} +
+
Secret Key
+ + + + {/if} +
diff --git a/src/routes/reset/password.json.ts b/src/routes/reset/password.json.ts new file mode 100644 index 000000000..28e9d56e3 --- /dev/null +++ b/src/routes/reset/password.json.ts @@ -0,0 +1,27 @@ +import type { RequestHandler } from '@sveltejs/kit'; +import * as db from '$lib/database'; +import { ErrorHandler, hashPassword } from '$lib/database'; + +export const post: RequestHandler = async (event) => { + const { secretKey, user } = await event.request.json(); + if (secretKey !== process.env.COOLIFY_SECRET_KEY) { + return { + status: 500, + body: { + error: 'Invalid secret key.' + } + }; + } + try { + const hashedPassword = await hashPassword(user.newPassword); + await db.prisma.user.update({ + where: { email: user.email }, + data: { password: hashedPassword } + }); + return { + status: 200 + }; + } catch (error) { + return ErrorHandler(error); + } +};