Skip to content

Commit 8f55ed9

Browse files
committed
security advisory fixes opened by kolega-ai-dev
1 parent e5f794c commit 8f55ed9

File tree

7 files changed

+36
-13
lines changed

7 files changed

+36
-13
lines changed

src/app/(main)/admin/users/UserAddForm.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
TextField,
1111
} from '@umami/react-zen';
1212
import { useMessages, useUpdateQuery } from '@/components/hooks';
13+
import { messages } from '@/components/messages';
1314
import { ROLES } from '@/lib/constants';
1415

1516
export function UserAddForm({ onSave, onClose }) {
@@ -37,7 +38,10 @@ export function UserAddForm({ onSave, onClose }) {
3738
<FormField
3839
label={formatMessage(labels.password)}
3940
name="password"
40-
rules={{ required: formatMessage(labels.required) }}
41+
rules={{
42+
required: formatMessage(labels.required),
43+
minLength: { value: 8, message: formatMessage(messages.minPasswordLength, { n: '8' }) },
44+
}}
4145
>
4246
<PasswordField autoComplete="new-password" data-test="input-password" />
4347
</FormField>

src/app/api/auth/logout/route.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import redis from '@/lib/redis';
2+
import { parseRequest } from '@/lib/request';
23
import { ok } from '@/lib/response';
34

45
export async function POST(request: Request) {
6+
const { error } = await parseRequest(request);
7+
8+
if (error) {
9+
return error();
10+
}
11+
512
if (redis.enabled) {
613
const token = request.headers.get('authorization')?.split(' ')?.[1];
714

src/app/api/auth/sso/route.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { saveAuth } from '@/lib/auth';
22
import redis from '@/lib/redis';
33
import { parseRequest } from '@/lib/request';
4-
import { json } from '@/lib/response';
4+
import { json, serverError } from '@/lib/response';
55

66
export async function POST(request: Request) {
77
const { auth, error } = await parseRequest(request);
@@ -10,9 +10,13 @@ export async function POST(request: Request) {
1010
return error();
1111
}
1212

13-
if (redis.enabled) {
14-
const token = await saveAuth({ userId: auth.user.id }, 86400);
15-
16-
return json({ user: auth.user, token });
13+
if (!redis.enabled) {
14+
return serverError({
15+
message: 'Redis is disabled',
16+
});
1717
}
18+
19+
const token = await saveAuth({ userId: auth.user.id }, 86400);
20+
21+
return json({ user: auth.user, token });
1822
}

src/app/api/users/[userId]/route.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { z } from 'zod';
22
import { hashPassword } from '@/lib/password';
33
import { parseRequest } from '@/lib/request';
4-
import { badRequest, json, ok, unauthorized } from '@/lib/response';
4+
import { badRequest, json, notFound, ok, unauthorized } from '@/lib/response';
55
import { userRoleParam } from '@/lib/schema';
66
import { canDeleteUser, canUpdateUser, canViewUser } from '@/permissions';
77
import { deleteUser, getUser, getUserByUsername, updateUser } from '@/queries/prisma';
@@ -27,7 +27,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ user
2727
export async function POST(request: Request, { params }: { params: Promise<{ userId: string }> }) {
2828
const schema = z.object({
2929
username: z.string().max(255).optional(),
30-
password: z.string().max(255).optional(),
30+
password: z.string().min(8).max(255).optional(),
3131
role: userRoleParam.optional(),
3232
});
3333

@@ -47,6 +47,10 @@ export async function POST(request: Request, { params }: { params: Promise<{ use
4747

4848
const user = await getUser(userId);
4949

50+
if (!user) {
51+
return notFound();
52+
}
53+
5054
const data: any = {};
5155

5256
if (password) {

src/app/api/users/route.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import { uuid } from '@/lib/crypto';
44
import { hashPassword } from '@/lib/password';
55
import { parseRequest } from '@/lib/request';
66
import { badRequest, json, unauthorized } from '@/lib/response';
7+
import { userRoleParam } from '@/lib/schema';
78
import { canCreateUser } from '@/permissions';
89
import { createUser, getUserByUsername } from '@/queries/prisma';
910

1011
export async function POST(request: Request) {
1112
const schema = z.object({
1213
id: z.uuid().optional(),
1314
username: z.string().max(255),
14-
password: z.string(),
15-
role: z.string().regex(/admin|user|view-only/i),
15+
password: z.string().min(8).max(255),
16+
role: userRoleParam,
1617
});
1718

1819
const { auth, body, error } = await parseRequest(request, schema);

src/lib/auth.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import debug from 'debug';
22
import { ROLE_PERMISSIONS, ROLES, SHARE_TOKEN_HEADER } from '@/lib/constants';
3-
import { secret } from '@/lib/crypto';
4-
import { getRandomChars } from '@/lib/generate';
3+
import { createAuthKey, secret } from '@/lib/crypto';
54
import { createSecureToken, parseSecureToken, parseToken } from '@/lib/jwt';
65
import redis from '@/lib/redis';
76
import { ensureArray } from '@/lib/utils';
@@ -53,7 +52,7 @@ export async function checkAuth(request: Request) {
5352
}
5453

5554
export async function saveAuth(data: any, expire = 0) {
56-
const authKey = `auth:${getRandomChars(32)}`;
55+
const authKey = `auth:${createAuthKey()}`;
5756

5857
if (redis.enabled) {
5958
await redis.client.set(authKey, data);

src/lib/crypto.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,7 @@ export function uuid(...args: any) {
6363

6464
return process.env.USE_UUIDV7 ? v7() : v4();
6565
}
66+
67+
export function createAuthKey() {
68+
return crypto.randomBytes(16).toString('hex');
69+
}

0 commit comments

Comments
 (0)