From b96c1a23ec1ff9e35972bd3f715146abd2d20645 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 7 Apr 2022 23:26:06 +0200 Subject: [PATCH] fix: Ton of updates for users/teams --- src/lib/database/users.ts | 46 +++-- src/routes/__layout.svelte | 15 +- src/routes/applications/index.svelte | 5 +- src/routes/databases/index.svelte | 7 +- src/routes/destinations/index.svelte | 5 +- src/routes/iam/index.json.ts | 130 +++++++++++++ src/routes/iam/index.svelte | 178 ++++++++++++++++++ src/routes/iam/password.json.ts | 22 +++ .../{teams => iam/team}/[id]/__layout.svelte | 6 +- .../{teams => iam/team}/[id]/index.json.ts | 0 .../{teams => iam/team}/[id]/index.svelte | 12 +- .../team}/[id]/invitation/accept.json.ts | 0 .../team}/[id]/invitation/invite.json.ts | 0 .../team}/[id]/invitation/revoke.json.ts | 0 .../team}/[id]/permission/change.json.ts | 0 .../team}/[id]/remove/user.json.ts | 0 src/routes/services/index.svelte | 7 +- src/routes/sources/index.svelte | 5 +- src/routes/teams/index.json.ts | 27 --- src/routes/teams/index.svelte | 146 -------------- 20 files changed, 383 insertions(+), 228 deletions(-) create mode 100644 src/routes/iam/index.json.ts create mode 100644 src/routes/iam/index.svelte create mode 100644 src/routes/iam/password.json.ts rename src/routes/{teams => iam/team}/[id]/__layout.svelte (83%) rename src/routes/{teams => iam/team}/[id]/index.json.ts (100%) rename src/routes/{teams => iam/team}/[id]/index.svelte (94%) rename src/routes/{teams => iam/team}/[id]/invitation/accept.json.ts (100%) rename src/routes/{teams => iam/team}/[id]/invitation/invite.json.ts (100%) rename src/routes/{teams => iam/team}/[id]/invitation/revoke.json.ts (100%) rename src/routes/{teams => iam/team}/[id]/permission/change.json.ts (100%) rename src/routes/{teams => iam/team}/[id]/remove/user.json.ts (100%) delete mode 100644 src/routes/teams/index.json.ts delete mode 100644 src/routes/teams/index.svelte diff --git a/src/lib/database/users.ts b/src/lib/database/users.ts index 7e5cc481e..36b130b35 100644 --- a/src/lib/database/users.ts +++ b/src/lib/database/users.ts @@ -32,26 +32,42 @@ export async function login({ email, password, isLogin }) { if (users === 0) { await prisma.setting.update({ where: { id }, data: { isRegistrationEnabled: false } }); // Create default network & start Coolify Proxy - asyncExecShell(`docker network create --attachable coolify`) - .then(() => { - console.log('Network created'); - }) - .catch(() => { - console.log('Network already exists.'); - }); - - startCoolifyProxy('/var/run/docker.sock') - .then(() => { - console.log('Coolify Proxy started.'); - }) - .catch((err) => { - console.log(err); - }); + await asyncExecShell(`docker network create --attachable coolify`); + await startCoolifyProxy('/var/run/docker.sock'); uid = '0'; } if (userFound) { if (userFound.type === 'email') { + if (userFound.password === 'RESETME') { + const hashedPassword = await hashPassword(password); + if (userFound.updatedAt < new Date(Date.now() - 1000 * 60 * 10)) { + await prisma.user.update({ + where: { email: userFound.email }, + data: { password: 'RESETTIMEOUT' } + }); + throw { + error: 'Password reset link has expired. Please request a new one.' + }; + } else { + await prisma.user.update({ + where: { email: userFound.email }, + data: { password: hashedPassword } + }); + return { + status: 200, + headers: { + 'Set-Cookie': `teamId=${uid}; HttpOnly; Path=/; Max-Age=15778800;` + }, + body: { + userId: userFound.id, + teamId: userFound.id, + permission: userFound.permission, + isAdmin: true + } + }; + } + } const passwordMatch = await bcrypt.compare(password, userFound.password); if (!passwordMatch) { throw { diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte index 010298059..09b030328 100644 --- a/src/routes/__layout.svelte +++ b/src/routes/__layout.svelte @@ -434,13 +434,12 @@
- + {#if $session.teamId === '0'} {/if} +
{:else}
- {#if $session.teamId === '0' && ownApplications.length > 0 && otherApplications.length > 0} -
Current Team
- {/if}
{#each ownApplications as application} {/each}
{#if otherApplications.length > 0 && $session.teamId === '0'} -
Others
+
Other Applications
{#each otherApplications as application} diff --git a/src/routes/databases/index.svelte b/src/routes/databases/index.svelte index 5e271bcfe..7185e7f28 100644 --- a/src/routes/databases/index.svelte +++ b/src/routes/databases/index.svelte @@ -52,9 +52,6 @@
{:else}
- {#if $session.teamId === '0' && ownDatabases.length > 0 && otherDatabases.length > 0} -
Current Team
- {/if} {/each}
{#if otherDatabases.length > 0 && $session.teamId === '0'} -
Others
+
Other Databases
{:else}
- {#if $session.teamId === '0' && ownDestinations.length > 0 && otherDestinations.length > 0} -
Current Team
- {/if}
{#if otherDestinations.length > 0 && $session.teamId === '0'} -
Others
+
Other Destinations
{#each otherDestinations as destination} diff --git a/src/routes/iam/index.json.ts b/src/routes/iam/index.json.ts new file mode 100644 index 000000000..fa44e55ba --- /dev/null +++ b/src/routes/iam/index.json.ts @@ -0,0 +1,130 @@ +import { getUserDetails } from '$lib/common'; +import * as db from '$lib/database'; +import { ErrorHandler } from '$lib/database'; +import type { RequestHandler } from '@sveltejs/kit'; + +export const get: RequestHandler = async (event) => { + const { teamId, userId, status, body } = await getUserDetails(event); + if (status === 401) return { status, body }; + + try { + const account = await db.prisma.user.findUnique({ + where: { id: userId }, + select: { id: true, email: true, teams: true } + }); + let accounts = []; + if (teamId === '0') { + accounts = await db.prisma.user.findMany({ select: { id: true, email: true, teams: true } }); + } + + const teams = await db.prisma.permission.findMany({ + where: { userId: teamId === '0' ? undefined : userId }, + include: { team: { include: { _count: { select: { users: true } } } } } + }); + + const invitations = await db.prisma.teamInvitation.findMany({ where: { uid: userId } }); + return { + status: 200, + body: { + teams, + invitations, + account, + accounts + } + }; + } catch (error) { + return ErrorHandler(error); + } +}; + +export const post: RequestHandler = async (event) => { + const { teamId, userId, status, body } = await getUserDetails(event); + if (status === 401) return { status, body }; + if (teamId !== '0') + return { status: 401, body: { message: 'You are not authorized to perform this action' } }; + + const { id } = await event.request.json(); + try { + const aloneInTeams = await db.prisma.team.findMany({ where: { users: { every: { id } } } }); + if (aloneInTeams.length > 0) { + for (const team of aloneInTeams) { + const applications = await db.prisma.application.findMany({ + where: { teams: { every: { id: team.id } } } + }); + if (applications.length > 0) { + for (const application of applications) { + await db.prisma.application.update({ + where: { id: application.id }, + data: { teams: { connect: { id: '0' } } } + }); + } + } + const services = await db.prisma.service.findMany({ + where: { teams: { every: { id: team.id } } } + }); + if (services.length > 0) { + for (const service of services) { + await db.prisma.service.update({ + where: { id: service.id }, + data: { teams: { connect: { id: '0' } } } + }); + } + } + const databases = await db.prisma.database.findMany({ + where: { teams: { every: { id: team.id } } } + }); + if (databases.length > 0) { + for (const database of databases) { + await db.prisma.database.update({ + where: { id: database.id }, + data: { teams: { connect: { id: '0' } } } + }); + } + } + const sources = await db.prisma.gitSource.findMany({ + where: { teams: { every: { id: team.id } } } + }); + if (sources.length > 0) { + for (const source of sources) { + await db.prisma.gitSource.update({ + where: { id: source.id }, + data: { teams: { connect: { id: '0' } } } + }); + } + } + const destinations = await db.prisma.destinationDocker.findMany({ + where: { teams: { every: { id: team.id } } } + }); + if (destinations.length > 0) { + for (const destination of destinations) { + await db.prisma.destinationDocker.update({ + where: { id: destination.id }, + data: { teams: { connect: { id: '0' } } } + }); + } + } + await db.prisma.teamInvitation.deleteMany({ where: { teamId: team.id } }); + await db.prisma.permission.deleteMany({ where: { teamId: team.id } }); + await db.prisma.user.delete({ where: { id } }); + await db.prisma.team.delete({ where: { id: team.id } }); + } + } + + const notAloneInTeams = await db.prisma.team.findMany({ where: { users: { some: { id } } } }); + if (notAloneInTeams.length > 0) { + for (const team of notAloneInTeams) { + await db.prisma.team.update({ + where: { id: team.id }, + data: { users: { disconnect: { id } } } + }); + } + } + return { + status: 201 + }; + } catch (error) { + return { + status: 500 + }; + } +}; diff --git a/src/routes/iam/index.svelte b/src/routes/iam/index.svelte new file mode 100644 index 000000000..0541abbb8 --- /dev/null +++ b/src/routes/iam/index.svelte @@ -0,0 +1,178 @@ + + + + +
+
Identity and Access Management System
+
+ + +
+ {#if $session.teamId === '0' && accounts.length > 0} +
Accounts
+ {:else} +
Account
+ {/if} +
+ + + + {#if accounts.length > 1} + + + {/if} + + + + + {#each accounts as account} + + + + + {/each} + +
EmailActions
{account.email} +
resetPassword(account.id)}> + +
+
deleteUser(account.id)}> + +
+
+
+
+ +
diff --git a/src/routes/iam/password.json.ts b/src/routes/iam/password.json.ts new file mode 100644 index 000000000..b8ba2ca8e --- /dev/null +++ b/src/routes/iam/password.json.ts @@ -0,0 +1,22 @@ +import { getUserDetails } from '$lib/common'; +import * as db from '$lib/database'; +import { ErrorHandler } from '$lib/database'; +import type { RequestHandler } from '@sveltejs/kit'; + +export const post: RequestHandler = async (event) => { + const { teamId, userId, status, body } = await getUserDetails(event); + if (status === 401) return { status, body }; + + const { id } = await event.request.json(); + try { + await db.prisma.user.update({ where: { id }, data: { password: 'RESETME' } }); + return { + status: 201 + }; + } catch (error) { + console.log(error); + return { + status: 500 + }; + } +}; diff --git a/src/routes/teams/[id]/__layout.svelte b/src/routes/iam/team/[id]/__layout.svelte similarity index 83% rename from src/routes/teams/[id]/__layout.svelte rename to src/routes/iam/team/[id]/__layout.svelte index 9ad4eb110..972ca111f 100644 --- a/src/routes/teams/[id]/__layout.svelte +++ b/src/routes/iam/team/[id]/__layout.svelte @@ -1,14 +1,14 @@ diff --git a/src/routes/teams/[id]/index.json.ts b/src/routes/iam/team/[id]/index.json.ts similarity index 100% rename from src/routes/teams/[id]/index.json.ts rename to src/routes/iam/team/[id]/index.json.ts diff --git a/src/routes/teams/[id]/index.svelte b/src/routes/iam/team/[id]/index.svelte similarity index 94% rename from src/routes/teams/[id]/index.svelte rename to src/routes/iam/team/[id]/index.svelte index 964b57612..541b21379 100644 --- a/src/routes/teams/[id]/index.svelte +++ b/src/routes/iam/team/[id]/index.svelte @@ -1,7 +1,7 @@ - - - -
-
Teams
- {#if $session.isAdmin} - - - - {/if} -
- -{#if invitations.length > 0} -
-
-
Pending invitations
-
-
- {#each invitations as invitation} -
-
- Invited to {invitation.teamName} with - {invitation.permission} permission. -
- - -
- {/each} -
-
-{/if} -