@webstudio-is/trpc-interface 0.90.0 → 0.260.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +26 -25
- package/src/authorize/project.server.test.ts +443 -0
- package/src/authorize/project.server.ts +309 -121
- package/src/authorize/role.ts +18 -0
- package/src/context/context.server.ts +59 -24
- package/src/context/errors.server.ts +16 -0
- package/src/context/router.server.ts +19 -0
- package/src/index.server.ts +15 -3
- package/src/shared/client.ts +0 -2
- package/src/shared/deployment.ts +23 -6
- package/src/shared/domain.ts +3 -3
- package/src/shared/plan-client.server.ts +7 -0
- package/src/shared/plan-features.ts +7 -0
- package/src/shared/shared-router.ts +0 -2
- package/src/shared/trpc.ts +5 -1
- package/src/trpc-caller-link.test.ts +1 -1
- package/src/trpc-caller-link.ts +1 -2
- package/tsconfig.json +3 -0
- package/lib/authorize/authorization-token.server.js +0 -72
- package/lib/authorize/project.server.js +0 -103
- package/lib/cjs/authorize/authorization-token.server.js +0 -92
- package/lib/cjs/authorize/project.server.js +0 -123
- package/lib/cjs/context/context.server.js +0 -16
- package/lib/cjs/context/errors.server.js +0 -29
- package/lib/cjs/index.js +0 -18
- package/lib/cjs/index.server.js +0 -40
- package/lib/cjs/package.json +0 -1
- package/lib/cjs/shared/authorization-router.js +0 -184
- package/lib/cjs/shared/client.js +0 -63
- package/lib/cjs/shared/deployment.js +0 -51
- package/lib/cjs/shared/domain.js +0 -98
- package/lib/cjs/shared/shared-router.js +0 -32
- package/lib/cjs/shared/trpc.js +0 -31
- package/lib/cjs/trpc-caller-link.js +0 -46
- package/lib/context/context.server.js +0 -0
- package/lib/context/errors.server.js +0 -9
- package/lib/index.js +0 -1
- package/lib/index.server.js +0 -10
- package/lib/shared/authorization-router.js +0 -164
- package/lib/shared/client.js +0 -35
- package/lib/shared/deployment.js +0 -31
- package/lib/shared/domain.js +0 -78
- package/lib/shared/shared-router.js +0 -12
- package/lib/shared/trpc.js +0 -11
- package/lib/trpc-caller-link.js +0 -26
- package/lib/types/authorize/authorization-token.server.d.ts +0 -21
- package/lib/types/authorize/project.server.d.ts +0 -25
- package/lib/types/context/context.server.d.ts +0 -53
- package/lib/types/context/errors.server.d.ts +0 -1
- package/lib/types/index.d.ts +0 -1
- package/lib/types/index.server.d.ts +0 -7
- package/lib/types/shared/authorization-router.d.ts +0 -276
- package/lib/types/shared/client.d.ts +0 -8
- package/lib/types/shared/deployment.d.ts +0 -45
- package/lib/types/shared/domain.d.ts +0 -119
- package/lib/types/shared/shared-router.d.ts +0 -415
- package/lib/types/shared/trpc.d.ts +0 -48
- package/lib/types/trpc-caller-link.d.ts +0 -16
- package/lib/types/trpc-caller-link.test.d.ts +0 -49
- package/src/authorize/authorization-token.server.ts +0 -106
- package/src/shared/authorization-router.ts +0 -198
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { router, procedure } from "./trpc";
|
|
3
|
-
|
|
4
|
-
import { prisma } from "@webstudio-is/prisma-client";
|
|
5
|
-
|
|
6
|
-
const Relation = z.enum(["viewers", "editors", "builders", "owners"]);
|
|
7
|
-
const AuthPermit = z.enum(["view", "edit", "build", "own"]);
|
|
8
|
-
export type AuthPermit = z.infer<typeof AuthPermit>;
|
|
9
|
-
|
|
10
|
-
const DeleteCreateInput = z.discriminatedUnion("namespace", [
|
|
11
|
-
z.object({
|
|
12
|
-
namespace: z.literal("Project"),
|
|
13
|
-
id: z.string(),
|
|
14
|
-
relation: Relation,
|
|
15
|
-
|
|
16
|
-
subjectSet: z.discriminatedUnion("namespace", [
|
|
17
|
-
z.object({
|
|
18
|
-
namespace: z.literal("User"),
|
|
19
|
-
id: z.string(),
|
|
20
|
-
}),
|
|
21
|
-
z.object({
|
|
22
|
-
namespace: z.literal("Token"),
|
|
23
|
-
id: z.string(),
|
|
24
|
-
}),
|
|
25
|
-
z.object({
|
|
26
|
-
namespace: z.literal("Email"),
|
|
27
|
-
id: z.string(),
|
|
28
|
-
relation: z.literal("owners"),
|
|
29
|
-
}),
|
|
30
|
-
]),
|
|
31
|
-
}),
|
|
32
|
-
|
|
33
|
-
z.object({
|
|
34
|
-
namespace: z.literal("Email"),
|
|
35
|
-
id: z.string(),
|
|
36
|
-
relation: z.enum(["owners"]),
|
|
37
|
-
subjectSet: z.object({
|
|
38
|
-
namespace: z.literal("User"),
|
|
39
|
-
id: z.string(),
|
|
40
|
-
}),
|
|
41
|
-
}),
|
|
42
|
-
]);
|
|
43
|
-
|
|
44
|
-
export const authorizationRouter = router({
|
|
45
|
-
/**
|
|
46
|
-
* Relation expansion in authorize looks like a tree
|
|
47
|
-
*
|
|
48
|
-
* :#@Project:AliceProjectUUID#viewers
|
|
49
|
-
* :#@Email:bob@bob.com#owner
|
|
50
|
-
* :#@User:BobUUID️
|
|
51
|
-
* :#@Token:LinkRandomSequence️
|
|
52
|
-
*
|
|
53
|
-
* We don't need the whole tree in UI and need only the leaf nodes.
|
|
54
|
-
* i.e. @User:BobUUID️, @Token:LinkRandomSequence️ and the root relation i.e "viewers"
|
|
55
|
-
*/
|
|
56
|
-
expandLeafNodes: procedure
|
|
57
|
-
.input(
|
|
58
|
-
z.object({
|
|
59
|
-
namespace: z.literal("Project"),
|
|
60
|
-
id: z.string(),
|
|
61
|
-
})
|
|
62
|
-
)
|
|
63
|
-
.output(
|
|
64
|
-
z.array(
|
|
65
|
-
z.object({
|
|
66
|
-
// top level relation
|
|
67
|
-
relation: Relation,
|
|
68
|
-
// subjectSet
|
|
69
|
-
namespace: z.enum(["Email", "User", "Token"]),
|
|
70
|
-
id: z.string(),
|
|
71
|
-
})
|
|
72
|
-
)
|
|
73
|
-
)
|
|
74
|
-
.query(async ({ input }) => {
|
|
75
|
-
// Implement ory expand, on all relations
|
|
76
|
-
const { namespace, id } = input;
|
|
77
|
-
if (namespace !== "Project") {
|
|
78
|
-
throw new Error("Not implemented");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// At OSS we support only owner relation for the users
|
|
82
|
-
const ownerRow = await prisma.project.findUnique({
|
|
83
|
-
where: {
|
|
84
|
-
id,
|
|
85
|
-
},
|
|
86
|
-
select: {
|
|
87
|
-
userId: true,
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
const tokenRows = await prisma.authorizationToken.findMany({
|
|
92
|
-
where: {
|
|
93
|
-
projectId: id,
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const leafSubjectSets = [];
|
|
98
|
-
|
|
99
|
-
if (ownerRow !== null && ownerRow.userId !== null) {
|
|
100
|
-
leafSubjectSets.push({
|
|
101
|
-
namespace: "User",
|
|
102
|
-
id: ownerRow.userId,
|
|
103
|
-
relation: "owners",
|
|
104
|
-
} as const);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
for (const tokenRow of tokenRows) {
|
|
108
|
-
leafSubjectSets.push({
|
|
109
|
-
namespace: "Token",
|
|
110
|
-
id: tokenRow.token,
|
|
111
|
-
relation: tokenRow.relation,
|
|
112
|
-
} as const);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return leafSubjectSets;
|
|
116
|
-
}),
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Check if subject has permit on the resource
|
|
120
|
-
*/
|
|
121
|
-
check: procedure
|
|
122
|
-
.input(
|
|
123
|
-
z.object({
|
|
124
|
-
namespace: z.enum(["Project"]),
|
|
125
|
-
id: z.string(),
|
|
126
|
-
|
|
127
|
-
permit: AuthPermit,
|
|
128
|
-
|
|
129
|
-
subjectSet: z.object({
|
|
130
|
-
namespace: z.enum(["User", "Token"]),
|
|
131
|
-
id: z.string(),
|
|
132
|
-
}),
|
|
133
|
-
})
|
|
134
|
-
)
|
|
135
|
-
.output(z.object({ allowed: z.boolean() }))
|
|
136
|
-
.query(async ({ input }) => {
|
|
137
|
-
const { subjectSet } = input;
|
|
138
|
-
|
|
139
|
-
if (subjectSet.namespace === "User") {
|
|
140
|
-
// We check only if the user is the owner of the project
|
|
141
|
-
const row = await prisma.project.findFirst({
|
|
142
|
-
where: {
|
|
143
|
-
id: input.id,
|
|
144
|
-
userId: subjectSet.id,
|
|
145
|
-
},
|
|
146
|
-
select: {
|
|
147
|
-
id: true,
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
return { allowed: row !== null };
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const permitToRelationRewrite = {
|
|
155
|
-
view: ["viewers", "editors", "builders"],
|
|
156
|
-
edit: ["editors", "builders"],
|
|
157
|
-
build: ["builders"],
|
|
158
|
-
} as const;
|
|
159
|
-
|
|
160
|
-
if (subjectSet.namespace === "Token" && input.permit !== "own") {
|
|
161
|
-
const row = await prisma.authorizationToken.findFirst({
|
|
162
|
-
where: {
|
|
163
|
-
token: subjectSet.id,
|
|
164
|
-
relation: {
|
|
165
|
-
in: [...permitToRelationRewrite[input.permit]],
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
select: { token: true },
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
return { allowed: row !== null };
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return { allowed: false };
|
|
175
|
-
}),
|
|
176
|
-
/**
|
|
177
|
-
* In OSS we extract owner relation from the Project table, and the rest from the authorizationToken table
|
|
178
|
-
*/
|
|
179
|
-
create: procedure.input(DeleteCreateInput).mutation(async ({ input }) => {
|
|
180
|
-
// Do nothing in OSS
|
|
181
|
-
}),
|
|
182
|
-
|
|
183
|
-
delete: procedure.input(DeleteCreateInput).mutation(async ({ input }) => {
|
|
184
|
-
// Do nothing in OSS
|
|
185
|
-
}),
|
|
186
|
-
patch: procedure
|
|
187
|
-
.input(
|
|
188
|
-
z.array(
|
|
189
|
-
z.object({
|
|
190
|
-
action: z.enum(["insert", "delete"]),
|
|
191
|
-
relationTuple: DeleteCreateInput,
|
|
192
|
-
})
|
|
193
|
-
)
|
|
194
|
-
)
|
|
195
|
-
.mutation(async ({ input }) => {
|
|
196
|
-
// Do nothing in OSS
|
|
197
|
-
}),
|
|
198
|
-
});
|