diff --git a/prisma/dbml/schema.dbml b/prisma/dbml/schema.dbml index 7742682..def2224 100644 --- a/prisma/dbml/schema.dbml +++ b/prisma/dbml/schema.dbml @@ -88,6 +88,7 @@ Table user_sessions { browser_name String browser_version String ip_login String + valid_until DateTime [not null] login_at DateTime [default: `now()`, not null] logout_at DateTime user_id String [not null] diff --git a/prisma/migrations/20260528141807_increate_limit_oauth_token/migration.sql b/prisma/migrations/20260528141807_increate_limit_oauth_token/migration.sql new file mode 100644 index 0000000..a896e3b --- /dev/null +++ b/prisma/migrations/20260528141807_increate_limit_oauth_token/migration.sql @@ -0,0 +1,12 @@ +-- DropForeignKey +ALTER TABLE "user_preferences" DROP CONSTRAINT "user_preferences_char_as_partner_id_fkey"; + +-- AlterTable +ALTER TABLE "user_oauth_accounts" ALTER COLUMN "provider_token" SET DATA TYPE TEXT, +ALTER COLUMN "refresh_token" SET DATA TYPE TEXT; + +-- AlterTable +ALTER TABLE "user_preferences" ALTER COLUMN "char_as_partner_id" DROP NOT NULL; + +-- AddForeignKey +ALTER TABLE "user_preferences" ADD CONSTRAINT "user_preferences_char_as_partner_id_fkey" FOREIGN KEY ("char_as_partner_id") REFERENCES "characters"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/20260528142420_add_expires_in_session/migration.sql b/prisma/migrations/20260528142420_add_expires_in_session/migration.sql new file mode 100644 index 0000000..8f4ed35 --- /dev/null +++ b/prisma/migrations/20260528142420_add_expires_in_session/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - Added the required column `valid_until` to the `user_sessions` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "user_sessions" ADD COLUMN "valid_until" TIMESTAMPTZ NOT NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 46b08f1..cdcde98 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -175,8 +175,8 @@ model UserOauthAccounts { provider_name auth_provider provider_sub String? @db.VarChar(255) provider_email String? @db.VarChar(255) - provider_token String? @db.VarChar(255) - refresh_token String? @db.VarChar(255) + provider_token String? @db.Text + refresh_token String? @db.Text expires_at DateTime? @db.Timestamptz() created_at DateTime @default(now()) @db.Timestamptz() updated_at DateTime @updatedAt @db.Timestamptz() @@ -194,7 +194,8 @@ model UserSession { browser_name String? @db.VarChar(50) browser_version String? @db.VarChar(50) ip_login String? @db.Inet() - login_at DateTime @default(now()) @db.Timestamptz() + valid_until DateTime @db.Timestamptz() + login_at DateTime @default(now()) @db.Timestamptz() logout_at DateTime? @db.Timestamptz() user_id String @db.Uuid diff --git a/src/modules/auth/repositories/WRITE/createUserWithOAuthCredentials.repository.ts b/src/modules/auth/repositories/WRITE/createUserWithOAuthCredentials.repository.ts new file mode 100644 index 0000000..4dd1ee6 --- /dev/null +++ b/src/modules/auth/repositories/WRITE/createUserWithOAuthCredentials.repository.ts @@ -0,0 +1,28 @@ +import { AppError } from "../../../../helpers/error/instances/app"; +import { prisma } from "../../../../utils/databases/prisma/connection"; +import { createUserViaOauth } from "../../../user/user.types"; + +export const createUserWithOAuthCredentialsRepository = async (payload: createUserViaOauth) => { + try { + const { oauthProvider, ...userData } = payload; + return await prisma.user.create({ + data: { + ...userData, + oauth_accounts: { + create: { + provider_name: oauthProvider.providerName, + provider_sub: oauthProvider.sub, + provider_token: oauthProvider.token, + refresh_token: oauthProvider.refreshToken, + expires_at: oauthProvider.expiresAt, + }, + }, + preferences: { + create: {}, + }, + }, + }); + } catch (error) { + throw new AppError(500, "Error creating user with OAuth credentials", error); + } +}; diff --git a/src/modules/auth/services/internal/OAuthUserProvision.service.ts b/src/modules/auth/services/internal/OAuthUserProvision.service.ts index 6672b36..f1ad78e 100644 --- a/src/modules/auth/services/internal/OAuthUserProvision.service.ts +++ b/src/modules/auth/services/internal/OAuthUserProvision.service.ts @@ -5,6 +5,7 @@ import { createUserViaOauth } from "../../../user/user.types"; import { createUserService } from "../../../user/services/internal/createUser.service"; import { AppError } from "../../../../helpers/error/instances/app"; import { findAuthIdentityByEmailAndProviderRepository } from "../../repositories/READ/findAuthIdentityByEmailAndProvider.repository"; +import { createUserWithOAuthCredentialsRepository } from "../../repositories/WRITE/createUserWithOAuthCredentials.repository"; export const OAuthUserProvisionService = async (payload: createUserViaOauth, userHeaderInfo: UserHeaderInformation) => { try { @@ -18,7 +19,7 @@ export const OAuthUserProvisionService = async (payload: createUserViaOauth, use return await createUserSessionService(checkExistingUser.id, userHeaderInfo); } else if (!checkExistingUser) { // No user with this email, create new user - const createdUser = await createUserService(payload); + const createdUser = await createUserWithOAuthCredentialsRepository(payload); return await createUserSessionService(createdUser.id, userHeaderInfo); } diff --git a/src/modules/user/user.types.ts b/src/modules/user/user.types.ts index 74659fb..f27d4dc 100644 --- a/src/modules/user/user.types.ts +++ b/src/modules/user/user.types.ts @@ -20,7 +20,7 @@ export interface createUserViaRegisterInput { } export interface createUserViaOauth extends createUserViaRegisterInput { oauthProvider: { - providerName: string; + providerName: "google" | "github"; sub: string; token: string; refreshToken?: string; diff --git a/src/modules/userSession/repositories/createUserSession.repository.ts b/src/modules/userSession/repositories/createUserSession.repository.ts index f63b29e..790f7ab 100644 --- a/src/modules/userSession/repositories/createUserSession.repository.ts +++ b/src/modules/userSession/repositories/createUserSession.repository.ts @@ -1,36 +1,28 @@ import { Prisma } from "@prisma/client"; import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; import { userSessionModel } from "../userSession.model"; -import { generateUUIDv7 } from "../../../helpers/databases/uuidv7"; -export const createUserSessionRepository = async ( - data: Omit, -) => { +export const createUserSessionRepository = async (data: Omit) => { try { return await userSessionModel.create({ data: { - id: generateUUIDv7(), ...data, }, select: { id: true, - isAuthenticated: true, - validUntil: true, + browser_name: true, + ip_login: true, + valid_until: true, user: { select: { id: true, - name: true, email: true, + fullname: true, username: true, avatar: true, - birthDate: true, - bioProfile: true, - preference: { - omit: { - updatedAt: true, - createdAt: true, - }, - }, + datebirth: true, + bio: true, + preferences: {}, }, }, }, diff --git a/src/modules/userSession/services/createUserSession.service.ts b/src/modules/userSession/services/createUserSession.service.ts index b965c92..6d5ce71 100644 --- a/src/modules/userSession/services/createUserSession.service.ts +++ b/src/modules/userSession/services/createUserSession.service.ts @@ -29,7 +29,7 @@ export const createUserSessionService = async (userId: string, userHeaderInfo: U await createUserSessionInRedisService({ userId, sessionId: createUserSession.id, - validUntil: createUserSession.validUntil, + validUntil: createUserSession.valid_until, }); // create a jwt token with a payload containing the created user session, then return jwt diff --git a/src/utils/databases/prisma/connection.ts b/src/utils/databases/prisma/connection.ts index 7e2704a..86bfd2f 100644 --- a/src/utils/databases/prisma/connection.ts +++ b/src/utils/databases/prisma/connection.ts @@ -9,4 +9,7 @@ const pool = new pg.Pool({ }); const adapter = new PrismaPg(pool); -export const prisma = new PrismaClient({ adapter }); +export const prisma = new PrismaClient({ + adapter, + log: process.env.ENABLE_PRISMA_LOG === "true" ? ["query", "error", "warn", "info"] : [], +});