Skip to content

Commit

Permalink
feat: expose owId to auth session (#629)
Browse files Browse the repository at this point in the history
This PR closes DOT-349.
  • Loading branch information
brage-andreas authored Oct 30, 2023
1 parent 8d2a939 commit 4b1c795
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 26 deletions.
2 changes: 2 additions & 0 deletions packages/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
27 changes: 15 additions & 12 deletions packages/auth/src/auth-options.ts
Original file line number Diff line number Diff line change
@@ -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
}

Expand All @@ -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: {
Expand All @@ -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
},
Expand Down
5 changes: 4 additions & 1 deletion packages/auth/src/dashboard.app.ts
Original file line number Diff line number Diff line change
@@ -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 }),
})
3 changes: 3 additions & 0 deletions packages/auth/src/web.app.ts
Original file line number Diff line number Diff line change
@@ -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 }),
})
29 changes: 18 additions & 11 deletions packages/core/src/modules/user/user-repository.ts
Original file line number Diff line number Diff line change
@@ -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<Database["owUser"]>): User => {
return UserSchema.parse(payload)
}
export const mapToUser = (payload: Selectable<Database["owUser"]>): User => UserSchema.parse(payload)

export interface UserRepository {
getById(id: UserId): Promise<User | undefined>
getAll(limit: number): Promise<User[]>
create(userWrite: UserWrite): Promise<User>
update(id: UserId, data: UserWrite): Promise<User | undefined>
getById: (id: UserId) => Promise<User | undefined>
getBySubject: (cognitoSubject: string) => Promise<User | undefined>
getAll: (limit: number) => Promise<User[]>
create: (userWrite: UserWrite) => Promise<User>
update: (id: UserId, data: UserWrite) => Promise<User>
}

export class UserRepositoryImpl implements UserRepository {
Expand All @@ -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)
Expand All @@ -34,6 +41,6 @@ export class UserRepositoryImpl implements UserRepository {
.where("id", "=", id)
.returningAll()
.executeTakeFirstOrThrow()
return user ? mapToUser(user) : undefined
return mapToUser(user)
}
}
13 changes: 11 additions & 2 deletions packages/core/src/modules/user/user-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import { NotificationPermissionsRepository } from "./notification-permissions-re
import { NotFoundError } from "../../errors/errors"

export interface UserService {
getUser(id: UserId): Promise<User | undefined>
getUserById(id: UserId): Promise<User | undefined>
getUserBySubject(id: User["cognitoSub"]): Promise<User | undefined>
getAllUsers(limit: number): Promise<User[]>
createUser(input: UserWrite): Promise<User>
updateUser(id: UserId, payload: UserWrite): Promise<User>
Expand All @@ -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
Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4b1c795

Please sign in to comment.