+4
server/index.ts
+4
server/index.ts
···
132
132
req.method === 'OPTIONS'
133
133
) {
134
134
res.setHeader('Access-Control-Allow-Origin', '*');
135
+
} else if (req.path.startsWith('/xrpc/')) {
136
+
// XRPC endpoints use Authorization header auth, not cookies, so CSRF isn't a concern
137
+
// Allow cross-origin requests for ATProto clients
138
+
res.setHeader('Access-Control-Allow-Origin', '*');
135
139
} else {
136
140
// For state-changing operations without origin, reject to prevent CSRF
137
141
return res.status(403).json({
+5
-5
server/storage.ts
+5
-5
server/storage.ts
···
3114
3114
conditions.push(sql`${notifications.indexedAt} <= ${seenAt}`);
3115
3115
}
3116
3116
3117
-
return await db
3117
+
return await this.db
3118
3118
.select()
3119
3119
.from(notifications)
3120
3120
.where(and(...conditions))
···
3123
3123
}
3124
3124
3125
3125
async getUnreadNotificationCount(recipientDid: string): Promise<number> {
3126
-
const result = await db
3126
+
const result = await this.db
3127
3127
.select({ count: sql<number>`count(*)` })
3128
3128
.from(notifications)
3129
3129
.where(
···
3155
3155
}
3156
3156
3157
3157
async createList(list: InsertList): Promise<List> {
3158
-
const [newList] = await db.insert(lists).values(list).returning();
3158
+
const [newList] = await this.db.insert(lists).values(list).returning();
3159
3159
return newList;
3160
3160
}
3161
3161
···
3709
3709
3710
3710
// Video job operations
3711
3711
async createVideoJob(job: InsertVideoJob): Promise<VideoJob> {
3712
-
const [videoJob] = await db.insert(videoJobs).values(job).returning();
3712
+
const [videoJob] = await this.db.insert(videoJobs).values(job).returning();
3713
3713
return videoJob;
3714
3714
}
3715
3715
3716
3716
async getVideoJob(jobId: string): Promise<VideoJob | undefined> {
3717
-
const [job] = await db
3717
+
const [job] = await this.db
3718
3718
.select()
3719
3719
.from(videoJobs)
3720
3720
.where(eq(videoJobs.jobId, jobId))