diff --git a/packages/auth/package.json b/packages/auth/package.json index 06572f820..b5ed0cccd 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -11,7 +11,9 @@ "type-check": "tsc --noEmit" }, "dependencies": { + "@dotkomonline/core": "workspace:*", "@dotkomonline/env": "workspace:*", + "@dotkomonline/db": "workspace:*", "next": "^13.5.6", "next-auth": "^4.24.4", "react": "^18.2.0", diff --git a/packages/auth/src/auth-options.ts b/packages/auth/src/auth-options.ts index 100ff011a..3bc3953d8 100644 --- a/packages/auth/src/auth-options.ts +++ b/packages/auth/src/auth-options.ts @@ -1,10 +1,11 @@ -import { DefaultSession, DefaultUser, User } from "next-auth" -import { type NextAuthOptions } from "next-auth" +import { type ServiceLayer } from "@dotkomonline/core" +import { type DefaultSession, type DefaultUser, type User, type NextAuthOptions } from "next-auth" import CognitoProvider from "next-auth/providers/cognito" declare module "next-auth" { interface Session extends DefaultSession { user: User + sub: string id: string } @@ -16,30 +17,30 @@ declare module "next-auth" { } } -export type AuthOptions = { +export interface AuthOptions { cognitoClientId: string cognitoClientSecret: string cognitoIssuer: string + core: ServiceLayer } export const getAuthOptions = ({ cognitoClientId, cognitoClientSecret, cognitoIssuer, + core, }: AuthOptions): NextAuthOptions => ({ providers: [ CognitoProvider({ clientId: cognitoClientId, clientSecret: cognitoClientSecret, issuer: cognitoIssuer, - profile: (profile): User => { - return { - id: profile.sub, - name: `${profile.given_name} ${profile.family_name}`, - email: profile.email, - image: profile.picture ?? undefined, - } - }, + profile: (profile): User => ({ + id: profile.sub, + name: `${profile.given_name} ${profile.family_name}`, + email: profile.email, + image: profile.picture ?? undefined, + }), }), ], session: { @@ -48,7 +49,9 @@ export const getAuthOptions = ({ callbacks: { async session({ session, token }) { if (token.sub) { - session.user.id = token.sub + const user = await core.userService.getUserBySubject(token.sub) + session.user.id = user.id + session.sub = token.sub } return session }, diff --git a/packages/auth/src/dashboard.app.ts b/packages/auth/src/dashboard.app.ts index d19f5f293..a0b6981aa 100644 --- a/packages/auth/src/dashboard.app.ts +++ b/packages/auth/src/dashboard.app.ts @@ -1,8 +1,11 @@ -import { getAuthOptions } from "./auth-options" import { env } from "@dotkomonline/env" +import { createServiceLayer } from "@dotkomonline/core" +import { kysely } from "@dotkomonline/db" +import { getAuthOptions } from "./auth-options" export const authOptions = getAuthOptions({ cognitoClientId: env.DASHBOARD_COGNITO_CLIENT_ID, cognitoClientSecret: env.DASHBOARD_COGNITO_CLIENT_SECRET, cognitoIssuer: env.DASHBOARD_COGNITO_ISSUER, + core: await createServiceLayer({ db: kysely }), }) diff --git a/packages/auth/src/web.app.ts b/packages/auth/src/web.app.ts index f2b79065a..716fac049 100644 --- a/packages/auth/src/web.app.ts +++ b/packages/auth/src/web.app.ts @@ -1,8 +1,11 @@ +import { createServiceLayer } from "@dotkomonline/core" import { getAuthOptions } from "./auth-options" +import { kysely } from "@dotkomonline/db" import { env } from "@dotkomonline/env" export const authOptions = getAuthOptions({ cognitoClientId: env.WEB_COGNITO_CLIENT_ID, cognitoClientSecret: env.WEB_COGNITO_CLIENT_SECRET, cognitoIssuer: env.WEB_COGNITO_ISSUER, + core: await createServiceLayer({ db: kysely }), }) diff --git a/packages/core/src/modules/user/user-repository.ts b/packages/core/src/modules/user/user-repository.ts index 54693865e..37759f056 100644 --- a/packages/core/src/modules/user/user-repository.ts +++ b/packages/core/src/modules/user/user-repository.ts @@ -1,16 +1,15 @@ -import { Database } from "@dotkomonline/db" -import { Kysely, Selectable } from "kysely" -import { type User, UserId, UserSchema, UserWrite } from "@dotkomonline/types" +import { type Database } from "@dotkomonline/db" +import { type Kysely, type Selectable } from "kysely" +import { type User, type UserId, UserSchema, type UserWrite } from "@dotkomonline/types" -export const mapToUser = (payload: Selectable): User => { - return UserSchema.parse(payload) -} +export const mapToUser = (payload: Selectable): User => UserSchema.parse(payload) export interface UserRepository { - getById(id: UserId): Promise - getAll(limit: number): Promise - create(userWrite: UserWrite): Promise - update(id: UserId, data: UserWrite): Promise + getById: (id: UserId) => Promise + getBySubject: (cognitoSubject: string) => Promise + getAll: (limit: number) => Promise + create: (userWrite: UserWrite) => Promise + update: (id: UserId, data: UserWrite) => Promise } export class UserRepositoryImpl implements UserRepository { @@ -19,6 +18,14 @@ export class UserRepositoryImpl implements UserRepository { const user = await this.db.selectFrom("owUser").selectAll().where("id", "=", id).executeTakeFirst() return user ? mapToUser(user) : undefined } + async getBySubject(cognitoSubject: string) { + const user = await this.db + .selectFrom("owUser") + .selectAll() + .where("cognitoSub", "=", cognitoSubject) + .executeTakeFirst() + return user ? mapToUser(user) : undefined + } async getAll(limit: number) { const users = await this.db.selectFrom("owUser").selectAll().limit(limit).execute() return users.map(mapToUser) @@ -34,6 +41,6 @@ export class UserRepositoryImpl implements UserRepository { .where("id", "=", id) .returningAll() .executeTakeFirstOrThrow() - return user ? mapToUser(user) : undefined + return mapToUser(user) } } diff --git a/packages/core/src/modules/user/user-service.ts b/packages/core/src/modules/user/user-service.ts index 5f3a6691e..404d66a9c 100644 --- a/packages/core/src/modules/user/user-service.ts +++ b/packages/core/src/modules/user/user-service.ts @@ -14,7 +14,8 @@ import { NotificationPermissionsRepository } from "./notification-permissions-re import { NotFoundError } from "../../errors/errors" export interface UserService { - getUser(id: UserId): Promise + getUserById(id: UserId): Promise + getUserBySubject(id: User["cognitoSub"]): Promise getAllUsers(limit: number): Promise createUser(input: UserWrite): Promise updateUser(id: UserId, payload: UserWrite): Promise @@ -36,12 +37,20 @@ export class UserServiceImpl implements UserService { return users } - async getUser(id: UserId) { + async getUserById(id: UserId) { const user = await this.userRepository.getById(id) if (!user) throw new NotFoundError(`User with ID:${id} not found`) return user } + async getUserBySubject(id: User["cognitoSub"]) { + const user = await this.userRepository.getBySubject(id) + if (!user) { + throw new NotFoundError(`User with subject:${id} not found`) + } + return user + } + async createUser(input: UserWrite) { const res = await this.userRepository.create(input) return res diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02694366b..6d894dd0f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -494,6 +494,12 @@ importers: packages/auth: dependencies: + '@dotkomonline/core': + specifier: workspace:* + version: link:../core + '@dotkomonline/db': + specifier: workspace:* + version: link:../db '@dotkomonline/env': specifier: workspace:* version: link:../env