enh
This commit is contained in:
parent
6bcf080593
commit
5bd0f8ded7
9 changed files with 3834 additions and 36 deletions
File diff suppressed because one or more lines are too long
7
apps/backend/drizzle/0075_cuddly_rocket_racer.sql
Normal file
7
apps/backend/drizzle/0075_cuddly_rocket_racer.sql
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
CREATE TABLE "mf"."unlogged_user_tokens" (
|
||||||
|
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "mf"."unlogged_user_tokens_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
|
||||||
|
"token" varchar(500) NOT NULL,
|
||||||
|
"added_at" timestamp DEFAULT now() NOT NULL,
|
||||||
|
"last_verified" timestamp,
|
||||||
|
CONSTRAINT "unlogged_user_tokens_token_unique" UNIQUE("token")
|
||||||
|
);
|
||||||
3755
apps/backend/drizzle/meta/0075_snapshot.json
Normal file
3755
apps/backend/drizzle/meta/0075_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -526,6 +526,13 @@
|
||||||
"when": 1771674555093,
|
"when": 1771674555093,
|
||||||
"tag": "0074_outgoing_black_cat",
|
"tag": "0074_outgoing_black_cat",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 75,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1772196660983,
|
||||||
|
"tag": "0075_cuddly_rocket_racer",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -420,6 +420,13 @@ export const notifCreds = mf.table('notif_creds', {
|
||||||
lastVerified: timestamp('last_verified'),
|
lastVerified: timestamp('last_verified'),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const unloggedUserTokens = mf.table('unlogged_user_tokens', {
|
||||||
|
id: integer().primaryKey().generatedAlwaysAsIdentity(),
|
||||||
|
token: varchar({ length: 500 }).notNull().unique(),
|
||||||
|
addedAt: timestamp('added_at').notNull().defaultNow(),
|
||||||
|
lastVerified: timestamp('last_verified'),
|
||||||
|
});
|
||||||
|
|
||||||
export const userNotifications = mf.table('user_notifications', {
|
export const userNotifications = mf.table('user_notifications', {
|
||||||
id: integer().primaryKey().generatedAlwaysAsIdentity(),
|
id: integer().primaryKey().generatedAlwaysAsIdentity(),
|
||||||
title: varchar('title', { length: 255 }).notNull(),
|
title: varchar('title', { length: 255 }).notNull(),
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { router, protectedProcedure } from '../trpc-index';
|
import { router, protectedProcedure, publicProcedure } from '../trpc-index';
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import { eq, and } from 'drizzle-orm';
|
import { eq, and } from 'drizzle-orm';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { db } from '../../db/db_index';
|
import { db } from '../../db/db_index';
|
||||||
import { users, userDetails, userCreds, notifCreds } from '../../db/schema';
|
import { users, userDetails, userCreds, notifCreds, unloggedUserTokens } from '../../db/schema';
|
||||||
import { ApiError } from '../../lib/api-error';
|
import { ApiError } from '../../lib/api-error';
|
||||||
import { jwtSecret } from 'src/lib/env-exporter';
|
import { jwtSecret } from 'src/lib/env-exporter';
|
||||||
import { generateSignedUrlFromS3Url } from '../../lib/s3-client';
|
import { generateSignedUrlFromS3Url } from '../../lib/s3-client';
|
||||||
|
|
@ -109,17 +109,15 @@ export const userRouter = router({
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
|
|
||||||
savePushToken: protectedProcedure
|
savePushToken: publicProcedure
|
||||||
.input(z.object({ token: z.string() }))
|
.input(z.object({ token: z.string() }))
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const userId = ctx.user.userId;
|
|
||||||
const { token } = input;
|
const { token } = input;
|
||||||
|
const userId = ctx.user?.userId;
|
||||||
|
|
||||||
if (!userId) {
|
if (userId) {
|
||||||
throw new ApiError('User not authenticated', 401);
|
// AUTHENTICATED USER
|
||||||
}
|
// Check if token exists in notif_creds for this user
|
||||||
|
|
||||||
// Check if this exact token already exists for this user
|
|
||||||
const existing = await db.query.notifCreds.findFirst({
|
const existing = await db.query.notifCreds.findFirst({
|
||||||
where: and(
|
where: and(
|
||||||
eq(notifCreds.userId, userId),
|
eq(notifCreds.userId, userId),
|
||||||
|
|
@ -134,7 +132,7 @@ export const userRouter = router({
|
||||||
.set({ lastVerified: new Date() })
|
.set({ lastVerified: new Date() })
|
||||||
.where(eq(notifCreds.id, existing.id));
|
.where(eq(notifCreds.id, existing.id));
|
||||||
} else {
|
} else {
|
||||||
// Insert new token
|
// Insert new token into notif_creds
|
||||||
await db.insert(notifCreds).values({
|
await db.insert(notifCreds).values({
|
||||||
userId,
|
userId,
|
||||||
token,
|
token,
|
||||||
|
|
@ -142,6 +140,31 @@ export const userRouter = router({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove from unlogged_user_tokens if it exists
|
||||||
|
await db
|
||||||
|
.delete(unloggedUserTokens)
|
||||||
|
.where(eq(unloggedUserTokens.token, token));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// UNAUTHENTICATED USER
|
||||||
|
// Save/update in unlogged_user_tokens
|
||||||
|
const existing = await db.query.unloggedUserTokens.findFirst({
|
||||||
|
where: eq(unloggedUserTokens.token, token),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
await db
|
||||||
|
.update(unloggedUserTokens)
|
||||||
|
.set({ lastVerified: new Date() })
|
||||||
|
.where(eq(unloggedUserTokens.id, existing.id));
|
||||||
|
} else {
|
||||||
|
await db.insert(unloggedUserTokens).values({
|
||||||
|
token,
|
||||||
|
lastVerified: new Date(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
@ -19,8 +19,7 @@ function NotifChecker(props: Props) {
|
||||||
const { notifPermission, expoPushToken } = useNotification();
|
const { notifPermission, expoPushToken } = useNotification();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
console.log({isAuthenticated, expoPushToken, notifPermission});
|
if (expoPushToken && notifPermission === 'granted') {
|
||||||
if (isAuthenticated && expoPushToken && notifPermission === 'granted') {
|
|
||||||
savePushTokenMutation.mutate(
|
savePushTokenMutation.mutate(
|
||||||
{ token: expoPushToken },
|
{ token: expoPushToken },
|
||||||
{
|
{
|
||||||
|
|
@ -30,7 +29,7 @@ function NotifChecker(props: Props) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [isAuthenticated, expoPushToken, notifPermission]);
|
}, [expoPushToken, notifPermission, isAuthenticated]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (notifPermission === "denied") {
|
if (notifPermission === "denied") {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue