feature(dashboard): actually add password production to overviews

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-01-21 15:19:50 +00:00
parent 08bfff94cf
commit f216a7b9c5
7 changed files with 192 additions and 39 deletions

View File

@@ -1,5 +1,6 @@
import {
Arctic,
COOKIE_OPTIONS,
createSession,
deleteSessionTokenCookie,
generateSessionToken,
@@ -11,12 +12,18 @@ import {
verifyPasswordHash,
} from '@openpanel/auth';
import { generateSecureId } from '@openpanel/common/server/id';
import { connectUserToOrganization, db, getUserAccount } from '@openpanel/db';
import {
connectUserToOrganization,
db,
getShareOverviewById,
getUserAccount,
} from '@openpanel/db';
import { sendEmail } from '@openpanel/email';
import {
zRequestResetPassword,
zResetPassword,
zSignInEmail,
zSignInShare,
zSignUpEmail,
} from '@openpanel/validation';
import * as bcrypt from 'bcrypt';
@@ -272,4 +279,42 @@ export const authRouter = createTRPCRouter({
session: publicProcedure.query(async ({ ctx }) => {
return ctx.session;
}),
signInShare: publicProcedure
.use(
rateLimitMiddleware({
max: 3,
windowMs: 30_000,
}),
)
.input(zSignInShare)
.mutation(async ({ input, ctx }) => {
const { password, shareId } = input;
const share = await getShareOverviewById(input.shareId);
if (!share) {
throw TRPCNotFoundError('Share not found');
}
if (!share.public) {
throw TRPCNotFoundError('Share is not public');
}
if (!share.password) {
throw TRPCNotFoundError('Share is not password protected');
}
const validPassword = await verifyPasswordHash(share.password, password);
if (!validPassword) {
throw TRPCAccessError('Incorrect password');
}
ctx.setCookie(`shared-overview-${shareId}`, '1', {
maxAge: 60 * 60 * 24 * 7,
...COOKIE_OPTIONS,
});
return true;
}),
});

View File

@@ -3,6 +3,7 @@ import ShortUniqueId from 'short-unique-id';
import { db } from '@openpanel/db';
import { zShareOverview } from '@openpanel/validation';
import { hashPassword } from '@openpanel/auth';
import { createTRPCRouter, protectedProcedure } from '../trpc';
const uid = new ShortUniqueId({ length: 6 });
@@ -11,6 +12,10 @@ export const shareRouter = createTRPCRouter({
shareOverview: protectedProcedure
.input(zShareOverview)
.mutation(async ({ input }) => {
const passwordHash = input.password
? await hashPassword(input.password)
: null;
return db.shareOverview.upsert({
where: {
projectId: input.projectId,
@@ -20,11 +25,11 @@ export const shareRouter = createTRPCRouter({
organizationId: input.organizationId,
projectId: input.projectId,
public: input.public,
password: input.password || null,
password: passwordHash,
},
update: {
public: input.public,
password: input.password,
password: passwordHash,
},
});
}),