Skip to content

Commit 75560f6

Browse files
committed
Merge branch 'dev' into main
2 parents 25331af + 41623d8 commit 75560f6

File tree

27 files changed

+450
-188
lines changed

27 files changed

+450
-188
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { trpc } from 'src/trpc/server';
22

33
import { makePublicProcedure } from './make-public';
4+
import { setJoinRequestsAllowedProcedure } from './set-join-requests-allowed';
45

56
export const privacyRouter = trpc.router({
67
makePublic: makePublicProcedure(),
8+
setJoinRequestsAllowed: setJoinRequestsAllowedProcedure(),
79
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { isNanoID } from '@stdlib/misc';
2+
import { checkRedlockSignalAborted } from '@stdlib/redlock';
3+
import { once } from 'lodash';
4+
import type { InferProcedureOpts } from 'src/trpc/helpers';
5+
import { authProcedure } from 'src/trpc/helpers';
6+
import { z } from 'zod';
7+
8+
const baseProcedure = authProcedure.input(
9+
z.object({
10+
groupId: z.string().refine(isNanoID),
11+
12+
areJoinRequestsAllowed: z.boolean(),
13+
}),
14+
);
15+
16+
export const setJoinRequestsAllowedProcedure = once(() =>
17+
baseProcedure.mutation(setJoinRequestsAllowed),
18+
);
19+
20+
export async function setJoinRequestsAllowed({
21+
ctx,
22+
input,
23+
}: InferProcedureOpts<typeof baseProcedure>) {
24+
return await ctx.usingLocks(
25+
[[`user-lock:${ctx.userId}`], [`group-lock:${input.groupId}`]],
26+
async (signals) => {
27+
return await ctx.dataAbstraction.transaction(async (dtrx) => {
28+
// Assert agent is subscribed
29+
30+
await ctx.assertUserSubscribed({ userId: ctx.userId });
31+
32+
// Check if user has sufficient permissions
33+
34+
await ctx.assertSufficientGroupPermissions({
35+
userId: ctx.userId,
36+
groupId: input.groupId,
37+
permission: 'editGroupSettings',
38+
});
39+
40+
await ctx.dataAbstraction.hmset(
41+
'group',
42+
input.groupId,
43+
{ 'are-join-requests-allowed': input.areJoinRequestsAllowed },
44+
{ dtrx },
45+
);
46+
47+
checkRedlockSignalAborted(signals);
48+
});
49+
},
50+
);
51+
}

apps/app-server/src/websocket/groups/change-user-role.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ export function registerGroupsChangeUserRole(
3939
await ctx.usingLocks(
4040
[
4141
[`user-lock:${ctx.userId}`],
42-
[`user-lock:${input.patientId}`],
42+
...(input.patientId !== ctx.userId
43+
? [[`user-lock:${input.patientId}`]]
44+
: []),
4345
[`group-lock:${input.groupId}`],
4446
],
4547
performCommunication,

apps/app-server/src/websocket/groups/join-requests/send.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,17 @@ export async function sendStep1({
5555

5656
await ctx.assertUserSubscribed({ userId: ctx.userId });
5757

58-
const [groupJoinRequestRejected, groupMemberRole] = await Promise.all([
58+
const [
59+
groupAreJoinRequestsAllowed,
60+
groupJoinRequestRejected,
61+
groupMemberRole,
62+
] = await Promise.all([
63+
ctx.dataAbstraction.hget(
64+
'group',
65+
input.groupId,
66+
'are-join-requests-allowed',
67+
),
68+
5969
ctx.dataAbstraction.hget(
6070
'group-join-request',
6171
`${input.groupId}:${ctx.userId}`,
@@ -69,6 +79,15 @@ export async function sendStep1({
6979
),
7080
]);
7181

82+
// Check if group allows join requests
83+
84+
if (!groupAreJoinRequestsAllowed) {
85+
throw new TRPCError({
86+
code: 'FORBIDDEN',
87+
message: 'This group does not allow join requests.',
88+
});
89+
}
90+
7291
// Check if user has been rejected from the group
7392

7493
if (groupJoinRequestRejected) {

apps/app-server/src/websocket/groups/remove-user.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ export function registerGroupsRemoveUser(fastify: ReturnType<typeof Fastify>) {
3636
await ctx.usingLocks(
3737
[
3838
[`user-lock:${ctx.userId}`],
39-
[`user-lock:${input.patientId}`],
39+
...(input.patientId !== ctx.userId
40+
? [[`user-lock:${input.patientId}`]]
41+
: []),
4042
[`group-lock:${input.groupId}`],
4143
],
4244
performCommunication,

apps/client/components.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ declare module '@vue/runtime-core' {
99
export interface GlobalComponents {
1010
BillingFrequencyToggle: typeof import('./src/components/BillingFrequencyToggle.vue')['default']
1111
Checkbox: typeof import('./src/components/Checkbox.vue')['default']
12+
Checklist: typeof import('./src/components/Checklist.vue')['default']
1213
ColorPalette: typeof import('./src/components/ColorPalette.vue')['default']
1314
ColorSquare: typeof import('./src/components/ColorSquare.vue')['default']
1415
Combobox: typeof import('./src/components/Combobox.vue')['default']
1516
CopyBtn: typeof import('./src/components/CopyBtn.vue')['default']
1617
CustomDialog: typeof import('./src/components/CustomDialog.vue')['default']
18+
CustomInfiniteScroll: typeof import('./src/components/CustomInfiniteScroll.vue')['default']
1719
DeepBtn: typeof import('./src/components/DeepBtn.vue')['default']
1820
DeepBtnDropdown: typeof import('./src/components/DeepBtnDropdown.vue')['default']
1921
DisplayBtn: typeof import('./src/components/DisplayBtn.vue')['default']
@@ -26,6 +28,7 @@ declare module '@vue/runtime-core' {
2628
MiniSidebarBtn: typeof import('./src/components/MiniSidebarBtn.vue')['default']
2729
PageItem: typeof import('./src/components/PageItem.vue')['default']
2830
PageItemContent: typeof import('./src/components/PageItemContent.vue')['default']
31+
PassthroughComponent: typeof import('./src/components/PassthroughComponent.vue')['default']
2932
PasswordField: typeof import('./src/components/PasswordField.vue')['default']
3033
QMenuHover: typeof import('./src/components/QMenuHover.vue')['default']
3134
Radio: typeof import('./src/components/Radio.vue')['default']

apps/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@deepnotes/client",
33
"description": "DeepNotes",
44
"homepage": "https://deepnotes.app",
5-
"version": "1.0.13",
5+
"version": "1.0.14",
66
"author": "Gustavo Toyota <[email protected]>",
77
"dependencies": {
88
"@_ueberdosis/prosemirror-tables": "~1.1.3",

apps/client/quasar.config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ module.exports = configure(function (ctx) {
6262
{ path: 'sodium.universal' },
6363
{ path: 'i18n.universal' },
6464
{ path: 'vue.universal' },
65-
{ path: 'disable-cache.universal' },
65+
66+
{ path: 'http-headers/disable-cache.universal' },
67+
{ path: 'http-headers/x-frame-options.universal' },
68+
{ path: 'http-headers/referrer-policy.universal' },
6669

6770
{ path: 'array-at-polyfill.client', server: false },
6871
{ path: 'logger.client', server: false },
File renamed without changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { boot } from 'quasar/wrappers';
2+
3+
export default boot(async ({ ssrContext }) => {
4+
ssrContext?.res.setHeader('Referrer-Policy', 'no-referrer');
5+
});

0 commit comments

Comments
 (0)