Compare commits
13 Commits
db747c4f7a
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c1670c5af | |||
| 7efd7a4deb | |||
| 4f9bb6adb7 | |||
| c2a6783f26 | |||
| a13e8d1c35 | |||
| f5f1c8ac42 | |||
| 4464328c0a | |||
| 8e3f1b5bd4 | |||
| fd2043ba7e | |||
| 765d4507c9 | |||
| 6793460d31 | |||
| 4dfefadc9e | |||
| 114d6ff2f5 |
@@ -1,12 +0,0 @@
|
|||||||
.git
|
|
||||||
.github
|
|
||||||
.node_modules
|
|
||||||
dist
|
|
||||||
coverage
|
|
||||||
*.log
|
|
||||||
.env*
|
|
||||||
test
|
|
||||||
*.spec.ts
|
|
||||||
*.e2e-spec.ts
|
|
||||||
README.md
|
|
||||||
AGENTS.md
|
|
||||||
@@ -8,11 +8,9 @@ RUN pnpm build
|
|||||||
|
|
||||||
FROM node:20-alpine
|
FROM node:20-alpine
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN npm i -g pnpm
|
COPY --from=builder /app/dist ./dist
|
||||||
COPY --from=builder /app/package.json ./package.json
|
COPY --from=builder /app/node_modules ./node_modules
|
||||||
COPY --from=builder /app/pnpm-lock.yaml ./pnpm-lock.yaml
|
|
||||||
COPY --from=builder /app/prisma ./prisma
|
COPY --from=builder /app/prisma ./prisma
|
||||||
COPY --from=builder /app/prisma.config.ts ./prisma.config.ts
|
COPY --from=builder /app/prisma.config.ts ./prisma.config.ts
|
||||||
COPY --from=builder /app/dist ./dist
|
COPY --from=builder /app/package.json ./package.json
|
||||||
RUN pnpm install --prod --frozen-lockfile
|
|
||||||
CMD ["node", "dist/src/main.js"]
|
CMD ["node", "dist/src/main.js"]
|
||||||
|
|||||||
@@ -47,9 +47,9 @@
|
|||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"ioredis": "^5.8.2",
|
"ioredis": "^5.8.2",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"helmet": "^8.1.0",
|
|
||||||
"passport": "^0.7.0",
|
"passport": "^0.7.0",
|
||||||
"passport-discord": "^0.1.4",
|
"passport-discord": "^0.1.4",
|
||||||
|
"helmet": "^8.1.0",
|
||||||
"passport-google-oauth20": "^2.0.0",
|
"passport-google-oauth20": "^2.0.0",
|
||||||
"passport-jwt": "^4.0.1",
|
"passport-jwt": "^4.0.1",
|
||||||
"pg": "^8.16.3",
|
"pg": "^8.16.3",
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
output = "../node_modules/.prisma/client"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
@@ -50,10 +49,10 @@ model User {
|
|||||||
activeDollId String? @map("active_doll_id")
|
activeDollId String? @map("active_doll_id")
|
||||||
activeDoll Doll? @relation("ActiveDoll", fields: [activeDollId], references: [id])
|
activeDoll Doll? @relation("ActiveDoll", fields: [activeDollId], references: [id])
|
||||||
|
|
||||||
sentFriendRequests FriendRequest[] @relation("SentFriendRequests")
|
sentFriendRequests FriendRequest[] @relation("SentFriendRequests")
|
||||||
receivedFriendRequests FriendRequest[] @relation("ReceivedFriendRequests")
|
receivedFriendRequests FriendRequest[] @relation("ReceivedFriendRequests")
|
||||||
userFriendships Friendship[] @relation("UserFriendships")
|
userFriendships Friendship[] @relation("UserFriendships")
|
||||||
friendFriendships Friendship[] @relation("FriendFriendships")
|
friendFriendships Friendship[] @relation("FriendFriendships")
|
||||||
dolls Doll[]
|
dolls Doll[]
|
||||||
authIdentities AuthIdentity[]
|
authIdentities AuthIdentity[]
|
||||||
authSessions AuthSession[]
|
authSessions AuthSession[]
|
||||||
@@ -63,17 +62,17 @@ model User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model AuthIdentity {
|
model AuthIdentity {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
provider AuthProvider
|
provider AuthProvider
|
||||||
providerSubject String @map("provider_subject")
|
providerSubject String @map("provider_subject")
|
||||||
providerEmail String? @map("provider_email")
|
providerEmail String? @map("provider_email")
|
||||||
providerName String? @map("provider_name")
|
providerName String? @map("provider_name")
|
||||||
providerUsername String? @map("provider_username")
|
providerUsername String? @map("provider_username")
|
||||||
providerPicture String? @map("provider_picture")
|
providerPicture String? @map("provider_picture")
|
||||||
emailVerified Boolean @default(false) @map("email_verified")
|
emailVerified Boolean @default(false) @map("email_verified")
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
updatedAt DateTime @updatedAt @map("updated_at")
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||||||
userId String @map("user_id")
|
userId String @map("user_id")
|
||||||
|
|
||||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
@@ -83,14 +82,14 @@ model AuthIdentity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model AuthSession {
|
model AuthSession {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
provider AuthProvider?
|
provider AuthProvider?
|
||||||
refreshTokenHash String @unique @map("refresh_token_hash")
|
refreshTokenHash String @unique @map("refresh_token_hash")
|
||||||
expiresAt DateTime @map("expires_at")
|
expiresAt DateTime @map("expires_at")
|
||||||
revokedAt DateTime? @map("revoked_at")
|
revokedAt DateTime? @map("revoked_at")
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
updatedAt DateTime @updatedAt @map("updated_at")
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||||||
userId String @map("user_id")
|
userId String @map("user_id")
|
||||||
|
|
||||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
@@ -99,13 +98,13 @@ model AuthSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model AuthExchangeCode {
|
model AuthExchangeCode {
|
||||||
id String @id @default(uuid())
|
id String @id @default(uuid())
|
||||||
provider AuthProvider
|
provider AuthProvider
|
||||||
codeHash String @unique @map("code_hash")
|
codeHash String @unique @map("code_hash")
|
||||||
expiresAt DateTime @map("expires_at")
|
expiresAt DateTime @map("expires_at")
|
||||||
consumedAt DateTime? @map("consumed_at")
|
consumedAt DateTime? @map("consumed_at")
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
userId String @map("user_id")
|
userId String @map("user_id")
|
||||||
|
|
||||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ function validateEnvironment(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate PORT if provided
|
// Validate PORT if provided
|
||||||
if (config.PORT && isNaN(Number(config.PORT))) {
|
if (config.PORT !== undefined && !Number.isFinite(Number(config.PORT))) {
|
||||||
throw new Error('PORT must be a valid number');
|
throw new Error('PORT must be a valid number');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,10 +108,6 @@ class RedisLifecycleService implements OnModuleDestroy {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('error', (err) => {
|
|
||||||
logger.error('Redis connection error', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
client.on('connect', () => {
|
client.on('connect', () => {
|
||||||
logger.log(`Connected to Redis at ${host}:${port}`);
|
logger.log(`Connected to Redis at ${host}:${port}`);
|
||||||
});
|
});
|
||||||
|
|||||||
4
src/types/socket.d.ts
vendored
4
src/types/socket.d.ts
vendored
@@ -9,9 +9,9 @@ export type AuthenticatedSocket = BaseSocket<
|
|||||||
{
|
{
|
||||||
user?: AuthenticatedUser;
|
user?: AuthenticatedUser;
|
||||||
userId?: string;
|
userId?: string;
|
||||||
senderName?: string;
|
|
||||||
senderNameCachedAt?: number;
|
|
||||||
activeDollId?: string | null;
|
activeDollId?: string | null;
|
||||||
friends?: Set<string>; // Set of friend user IDs
|
friends?: Set<string>; // Set of friend user IDs
|
||||||
|
senderName?: string;
|
||||||
|
senderNameCachedAt?: number;
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ export class ConnectionHandler {
|
|||||||
// Initialize defaults
|
// Initialize defaults
|
||||||
client.data.activeDollId = null;
|
client.data.activeDollId = null;
|
||||||
client.data.friends = new Set();
|
client.data.friends = new Set();
|
||||||
client.data.senderName = undefined;
|
|
||||||
// userId is not set yet, it will be set in handleClientInitialize
|
// userId is not set yet, it will be set in handleClientInitialize
|
||||||
|
|
||||||
this.logger.log(`WebSocket authenticated (Pending Init): ${payload.sub}`);
|
this.logger.log(`WebSocket authenticated (Pending Init): ${payload.sub}`);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
import { WsException } from '@nestjs/websockets';
|
import { WsException } from '@nestjs/websockets';
|
||||||
import type { AuthenticatedSocket } from '../../../types/socket';
|
import type { AuthenticatedSocket } from '../../../types/socket';
|
||||||
import { PrismaService } from '../../../database/prisma.service';
|
|
||||||
import { SendInteractionDto } from '../../dto/send-interaction.dto';
|
import { SendInteractionDto } from '../../dto/send-interaction.dto';
|
||||||
import { InteractionPayloadDto } from '../../dto/interaction-payload.dto';
|
import { InteractionPayloadDto } from '../../dto/interaction-payload.dto';
|
||||||
|
import { PrismaService } from '../../../database/prisma.service';
|
||||||
import { UserSocketService } from '../user-socket.service';
|
import { UserSocketService } from '../user-socket.service';
|
||||||
import { WsNotificationService } from '../ws-notification.service';
|
import { WsNotificationService } from '../ws-notification.service';
|
||||||
import { WS_EVENT } from '../ws-events';
|
import { WS_EVENT } from '../ws-events';
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ type MockSocket = {
|
|||||||
userId?: string;
|
userId?: string;
|
||||||
activeDollId?: string | null;
|
activeDollId?: string | null;
|
||||||
friends?: Set<string>;
|
friends?: Set<string>;
|
||||||
|
senderName?: string;
|
||||||
|
senderNameCachedAt?: number;
|
||||||
};
|
};
|
||||||
handshake?: any;
|
handshake?: any;
|
||||||
disconnect?: jest.Mock;
|
disconnect?: jest.Mock;
|
||||||
|
|||||||
@@ -132,12 +132,6 @@ export class StateGateway
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onModuleDestroy() {
|
|
||||||
if (this.redisSubscriber) {
|
|
||||||
this.redisSubscriber.removeAllListeners('message');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async isUserOnline(userId: string): Promise<boolean> {
|
async isUserOnline(userId: string): Promise<boolean> {
|
||||||
return this.userSocketService.isUserOnline(userId);
|
return this.userSocketService.isUserOnline(userId);
|
||||||
}
|
}
|
||||||
@@ -165,4 +159,10 @@ export class StateGateway
|
|||||||
) {
|
) {
|
||||||
await this.interactionHandler.handleSendInteraction(client, data);
|
await this.interactionHandler.handleSendInteraction(client, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onModuleDestroy() {
|
||||||
|
if (this.redisSubscriber) {
|
||||||
|
this.redisSubscriber.removeAllListeners('message');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user