@m5kdev/backend 0.5.0 → 0.7.0
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/dist/src/modules/ai/ai.service.d.ts +11 -13
- package/dist/src/modules/ai/ai.service.js +6 -6
- package/dist/src/modules/ai/ai.trpc.d.ts +1 -1
- package/dist/src/modules/auth/auth.lib.d.ts +8 -12
- package/dist/src/modules/auth/auth.lib.js +2 -2
- package/dist/src/modules/auth/auth.service.d.ts +17 -47
- package/dist/src/modules/auth/auth.service.js +79 -66
- package/dist/src/modules/auth/auth.trpc.d.ts +16 -16
- package/dist/src/modules/base/base.abstract.d.ts +3 -2
- package/dist/src/modules/base/base.abstract.js +10 -1
- package/dist/src/modules/base/base.actor.d.ts +68 -0
- package/dist/src/modules/base/base.actor.js +99 -0
- package/dist/src/modules/base/base.actor.test.d.ts +1 -0
- package/dist/src/modules/base/base.actor.test.js +58 -0
- package/dist/src/modules/base/base.grants.d.ts +3 -7
- package/dist/src/modules/base/base.grants.js +22 -10
- package/dist/src/modules/base/base.grants.test.js +16 -45
- package/dist/src/modules/base/base.procedure.d.ts +109 -0
- package/dist/src/modules/base/base.procedure.js +301 -0
- package/dist/src/modules/base/base.repository.d.ts +1 -0
- package/dist/src/modules/base/base.repository.js +12 -2
- package/dist/src/modules/base/base.service.d.ts +23 -23
- package/dist/src/modules/base/base.service.js +26 -12
- package/dist/src/modules/base/base.service.test.d.ts +1 -0
- package/dist/src/modules/base/base.service.test.js +443 -0
- package/dist/src/modules/billing/billing.service.d.ts +4 -25
- package/dist/src/modules/billing/billing.service.js +6 -6
- package/dist/src/modules/billing/billing.trpc.d.ts +2 -2
- package/dist/src/modules/billing/billing.trpc.js +4 -6
- package/dist/src/modules/connect/connect.repository.d.ts +3 -3
- package/dist/src/modules/connect/connect.service.d.ts +21 -13
- package/dist/src/modules/connect/connect.service.js +10 -8
- package/dist/src/modules/connect/connect.trpc.d.ts +2 -2
- package/dist/src/modules/recurrence/recurrence.service.d.ts +59 -8
- package/dist/src/modules/recurrence/recurrence.service.js +16 -14
- package/dist/src/modules/recurrence/recurrence.trpc.d.ts +3 -3
- package/dist/src/modules/recurrence/recurrence.trpc.js +1 -1
- package/dist/src/modules/social/social.service.d.ts +3 -4
- package/dist/src/modules/social/social.service.js +3 -3
- package/dist/src/modules/tag/tag.repository.js +27 -26
- package/dist/src/modules/tag/tag.service.d.ts +90 -15
- package/dist/src/modules/tag/tag.service.js +20 -12
- package/dist/src/modules/tag/tag.trpc.d.ts +3 -3
- package/dist/src/modules/workflow/workflow.service.d.ts +48 -8
- package/dist/src/modules/workflow/workflow.service.js +6 -6
- package/dist/src/modules/workflow/workflow.trpc.d.ts +2 -2
- package/dist/src/types.d.ts +19 -19
- package/dist/src/utils/trpc.d.ts +31 -41
- package/dist/src/utils/trpc.js +95 -0
- package/dist/src/utils/trpc.test.d.ts +1 -0
- package/dist/src/utils/trpc.test.js +154 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
package/dist/src/types.d.ts
CHANGED
|
@@ -4,13 +4,13 @@ import type { AuthService } from "./modules/auth/auth.service";
|
|
|
4
4
|
import type { BillingService } from "./modules/billing/billing.service";
|
|
5
5
|
import type { TRPCMethods } from "./utils/trpc";
|
|
6
6
|
export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcMethods: TRPCMethods, authService: AuthService, aiService: AIService<MastraInstance>, billingService: BillingService) => import("@trpc/server").TRPCBuiltRouter<{
|
|
7
|
-
ctx: import("./
|
|
7
|
+
ctx: import("./utils/trpc").Context;
|
|
8
8
|
meta: any;
|
|
9
9
|
errorShape: import("@trpc/server").TRPCDefaultErrorShape;
|
|
10
10
|
transformer: true;
|
|
11
11
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
12
12
|
auth: import("@trpc/server").TRPCBuiltRouter<{
|
|
13
|
-
ctx: import("./
|
|
13
|
+
ctx: import("./utils/trpc").Context;
|
|
14
14
|
meta: any;
|
|
15
15
|
errorShape: import("@trpc/server").TRPCDefaultErrorShape;
|
|
16
16
|
transformer: true;
|
|
@@ -58,10 +58,10 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
58
58
|
input: void;
|
|
59
59
|
output: {
|
|
60
60
|
id: string;
|
|
61
|
-
status: string;
|
|
62
61
|
createdAt: Date;
|
|
63
62
|
updatedAt: Date | null;
|
|
64
63
|
expiresAt: Date | null;
|
|
64
|
+
status: string;
|
|
65
65
|
claimUserId: string | null;
|
|
66
66
|
claimedAt: Date | null;
|
|
67
67
|
claimedEmail: string | null;
|
|
@@ -76,11 +76,11 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
76
76
|
output: {
|
|
77
77
|
id: string;
|
|
78
78
|
email: string;
|
|
79
|
-
url: string;
|
|
80
79
|
createdAt: Date;
|
|
81
|
-
userId: string;
|
|
82
80
|
expiresAt: Date | null;
|
|
81
|
+
userId: string;
|
|
83
82
|
claimId: string;
|
|
83
|
+
url: string;
|
|
84
84
|
};
|
|
85
85
|
meta: any;
|
|
86
86
|
}>;
|
|
@@ -91,11 +91,11 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
91
91
|
output: {
|
|
92
92
|
id: string;
|
|
93
93
|
email: string;
|
|
94
|
-
url: string;
|
|
95
94
|
createdAt: Date;
|
|
96
|
-
userId: string;
|
|
97
95
|
expiresAt: Date | null;
|
|
96
|
+
userId: string;
|
|
98
97
|
claimId: string;
|
|
98
|
+
url: string;
|
|
99
99
|
}[];
|
|
100
100
|
meta: any;
|
|
101
101
|
}>;
|
|
@@ -148,11 +148,11 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
148
148
|
input: void;
|
|
149
149
|
output: {
|
|
150
150
|
id: string;
|
|
151
|
-
email: string | null;
|
|
152
151
|
name: string | null;
|
|
153
|
-
|
|
152
|
+
email: string | null;
|
|
154
153
|
createdAt: Date;
|
|
155
154
|
updatedAt: Date | null;
|
|
155
|
+
status: string;
|
|
156
156
|
}[];
|
|
157
157
|
meta: any;
|
|
158
158
|
}>;
|
|
@@ -162,11 +162,11 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
162
162
|
};
|
|
163
163
|
output: {
|
|
164
164
|
id: string;
|
|
165
|
-
email: string | null;
|
|
166
165
|
name: string | null;
|
|
167
|
-
|
|
166
|
+
email: string | null;
|
|
168
167
|
createdAt: Date;
|
|
169
168
|
updatedAt: Date | null;
|
|
169
|
+
status: string;
|
|
170
170
|
};
|
|
171
171
|
meta: any;
|
|
172
172
|
}>;
|
|
@@ -193,11 +193,11 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
193
193
|
};
|
|
194
194
|
output: {
|
|
195
195
|
id: string;
|
|
196
|
-
email: string | null;
|
|
197
196
|
name: string | null;
|
|
198
|
-
|
|
197
|
+
email: string | null;
|
|
199
198
|
createdAt: Date;
|
|
200
199
|
updatedAt: Date | null;
|
|
200
|
+
status: string;
|
|
201
201
|
};
|
|
202
202
|
meta: any;
|
|
203
203
|
}>;
|
|
@@ -207,11 +207,11 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
207
207
|
};
|
|
208
208
|
output: {
|
|
209
209
|
id: string;
|
|
210
|
-
email: string | null;
|
|
211
210
|
name: string | null;
|
|
212
|
-
|
|
211
|
+
email: string | null;
|
|
213
212
|
createdAt: Date;
|
|
214
213
|
updatedAt: Date | null;
|
|
214
|
+
status: string;
|
|
215
215
|
};
|
|
216
216
|
meta: any;
|
|
217
217
|
}>;
|
|
@@ -221,11 +221,11 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
221
221
|
};
|
|
222
222
|
output: {
|
|
223
223
|
id: string;
|
|
224
|
-
email: string | null;
|
|
225
224
|
name: string | null;
|
|
226
|
-
|
|
225
|
+
email: string | null;
|
|
227
226
|
createdAt: Date;
|
|
228
227
|
updatedAt: Date | null;
|
|
228
|
+
status: string;
|
|
229
229
|
};
|
|
230
230
|
meta: any;
|
|
231
231
|
}>;
|
|
@@ -300,7 +300,7 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
300
300
|
}>;
|
|
301
301
|
}>>;
|
|
302
302
|
ai: import("@trpc/server").TRPCBuiltRouter<{
|
|
303
|
-
ctx: import("./
|
|
303
|
+
ctx: import("./utils/trpc").Context;
|
|
304
304
|
meta: any;
|
|
305
305
|
errorShape: import("@trpc/server").TRPCDefaultErrorShape;
|
|
306
306
|
transformer: true;
|
|
@@ -319,7 +319,7 @@ export declare const createAuthTRPCRouter: <MastraInstance extends Mastra>(trpcM
|
|
|
319
319
|
}>;
|
|
320
320
|
}>>;
|
|
321
321
|
billing: import("@trpc/server").TRPCBuiltRouter<{
|
|
322
|
-
ctx: import("./
|
|
322
|
+
ctx: import("./utils/trpc").Context;
|
|
323
323
|
meta: any;
|
|
324
324
|
errorShape: import("@trpc/server").TRPCDefaultErrorShape;
|
|
325
325
|
transformer: true;
|
package/dist/src/utils/trpc.d.ts
CHANGED
|
@@ -2,8 +2,29 @@ import type { transformer } from "@m5kdev/commons/utils/trpc";
|
|
|
2
2
|
import type { TRPCRootObject } from "@trpc/server";
|
|
3
3
|
import type { CreateExpressContextOptions } from "@trpc/server/adapters/express";
|
|
4
4
|
import type { Result } from "neverthrow";
|
|
5
|
-
import type { BetterAuth,
|
|
5
|
+
import type { BetterAuth, Session, User } from "../modules/auth/auth.lib";
|
|
6
|
+
import { type OrganizationActor, type TeamActor, type UserActor } from "../modules/base/base.actor";
|
|
6
7
|
import { ServerError } from "./errors";
|
|
8
|
+
export type RequestContext = {
|
|
9
|
+
session: Session | null;
|
|
10
|
+
user: User | null;
|
|
11
|
+
actor: UserActor | null;
|
|
12
|
+
};
|
|
13
|
+
export type Context = {
|
|
14
|
+
session: Session;
|
|
15
|
+
user: User;
|
|
16
|
+
actor: UserActor;
|
|
17
|
+
};
|
|
18
|
+
export type OrganizationContext = {
|
|
19
|
+
session: Session;
|
|
20
|
+
user: User;
|
|
21
|
+
actor: OrganizationActor;
|
|
22
|
+
};
|
|
23
|
+
export type TeamContext = {
|
|
24
|
+
session: Session;
|
|
25
|
+
user: User;
|
|
26
|
+
actor: TeamActor;
|
|
27
|
+
};
|
|
7
28
|
type TRPCCreate = TRPCRootObject<Context, any, {
|
|
8
29
|
transformer: typeof transformer;
|
|
9
30
|
}>;
|
|
@@ -13,46 +34,15 @@ export type TRPCMethods = {
|
|
|
13
34
|
privateProcedure: TRPCCreate["procedure"];
|
|
14
35
|
adminProcedure: TRPCCreate["procedure"];
|
|
15
36
|
};
|
|
16
|
-
export declare function createAuthContext(auth: BetterAuth): ({ req }: CreateExpressContextOptions) => Promise<
|
|
17
|
-
session: {
|
|
18
|
-
id: string;
|
|
19
|
-
createdAt: Date;
|
|
20
|
-
updatedAt: Date;
|
|
21
|
-
userId: string;
|
|
22
|
-
token: string;
|
|
23
|
-
expiresAt: Date;
|
|
24
|
-
ipAddress: string | null;
|
|
25
|
-
userAgent: string | null;
|
|
26
|
-
impersonatedBy: string | null;
|
|
27
|
-
activeOrganizationId: string | null;
|
|
28
|
-
activeOrganizationRole: string | null;
|
|
29
|
-
activeTeamId: string | null;
|
|
30
|
-
activeTeamRole: string | null;
|
|
31
|
-
};
|
|
32
|
-
user: {
|
|
33
|
-
id: string;
|
|
34
|
-
email: string;
|
|
35
|
-
name: string;
|
|
36
|
-
metadata: Record<string, unknown>;
|
|
37
|
-
emailVerified: boolean;
|
|
38
|
-
image: string | null;
|
|
39
|
-
createdAt: Date;
|
|
40
|
-
updatedAt: Date;
|
|
41
|
-
role: string | null;
|
|
42
|
-
banned: boolean | null;
|
|
43
|
-
banReason: string | null;
|
|
44
|
-
banExpires: Date | null;
|
|
45
|
-
stripeCustomerId: string | null;
|
|
46
|
-
paymentCustomerId: string | null;
|
|
47
|
-
paymentPlanTier: string | null;
|
|
48
|
-
paymentPlanExpiresAt: Date | null;
|
|
49
|
-
preferences: string | null;
|
|
50
|
-
onboarding: number | null;
|
|
51
|
-
flags: string | null;
|
|
52
|
-
};
|
|
53
|
-
}>;
|
|
37
|
+
export declare function createAuthContext(auth: BetterAuth): ({ req }: CreateExpressContextOptions) => Promise<RequestContext>;
|
|
54
38
|
export declare function handleAsyncTRPCResult<T>(result: Promise<Result<T, ServerError>>): Promise<T>;
|
|
55
39
|
export declare function handleTRPCResult<T>(result: Result<T, ServerError>): T;
|
|
56
|
-
export declare function verifyProtectedProcedureContext(ctx:
|
|
57
|
-
export declare function
|
|
40
|
+
export declare function verifyProtectedProcedureContext(ctx: RequestContext): Context;
|
|
41
|
+
export declare function verifyOrganizationProcedureContext(ctx: Context): OrganizationContext;
|
|
42
|
+
export declare function verifyTeamProcedureContext(ctx: Context): TeamContext;
|
|
43
|
+
export declare function verifyAdminProcedureContext(ctx: RequestContext): Context;
|
|
44
|
+
export declare function requireRequestUser(ctx: RequestContext): User;
|
|
45
|
+
export declare function requireRequestActor(ctx: RequestContext): UserActor;
|
|
46
|
+
export declare function requireRequestActor(ctx: RequestContext, scope: "organization"): OrganizationActor;
|
|
47
|
+
export declare function requireRequestActor(ctx: RequestContext, scope: "team"): TeamActor;
|
|
58
48
|
export {};
|
package/dist/src/utils/trpc.js
CHANGED
|
@@ -4,8 +4,13 @@ exports.createAuthContext = createAuthContext;
|
|
|
4
4
|
exports.handleAsyncTRPCResult = handleAsyncTRPCResult;
|
|
5
5
|
exports.handleTRPCResult = handleTRPCResult;
|
|
6
6
|
exports.verifyProtectedProcedureContext = verifyProtectedProcedureContext;
|
|
7
|
+
exports.verifyOrganizationProcedureContext = verifyOrganizationProcedureContext;
|
|
8
|
+
exports.verifyTeamProcedureContext = verifyTeamProcedureContext;
|
|
7
9
|
exports.verifyAdminProcedureContext = verifyAdminProcedureContext;
|
|
10
|
+
exports.requireRequestUser = requireRequestUser;
|
|
11
|
+
exports.requireRequestActor = requireRequestActor;
|
|
8
12
|
const node_1 = require("better-auth/node");
|
|
13
|
+
const base_actor_1 = require("../modules/base/base.actor");
|
|
9
14
|
const errors_1 = require("./errors");
|
|
10
15
|
const logger_1 = require("./logger");
|
|
11
16
|
function createAuthContext(auth) {
|
|
@@ -15,9 +20,11 @@ function createAuthContext(auth) {
|
|
|
15
20
|
});
|
|
16
21
|
const user = data?.user || null;
|
|
17
22
|
const session = data?.session || null;
|
|
23
|
+
const actor = user && session ? (0, base_actor_1.createActorFromContext)({ user, session }, "user") : null;
|
|
18
24
|
return {
|
|
19
25
|
session,
|
|
20
26
|
user,
|
|
27
|
+
actor,
|
|
21
28
|
};
|
|
22
29
|
};
|
|
23
30
|
}
|
|
@@ -37,6 +44,34 @@ function handleTRPCResult(result) {
|
|
|
37
44
|
return result.value;
|
|
38
45
|
}
|
|
39
46
|
function verifyProtectedProcedureContext(ctx) {
|
|
47
|
+
if (!ctx.user || !ctx.session || !ctx.actor) {
|
|
48
|
+
throw new errors_1.ServerError({
|
|
49
|
+
code: "UNAUTHORIZED",
|
|
50
|
+
layer: "controller",
|
|
51
|
+
layerName: "TRPCController",
|
|
52
|
+
}).toTRPC();
|
|
53
|
+
}
|
|
54
|
+
return ctx;
|
|
55
|
+
}
|
|
56
|
+
function verifyOrganizationProcedureContext(ctx) {
|
|
57
|
+
if (!ctx.user || !ctx.session) {
|
|
58
|
+
throw new errors_1.ServerError({
|
|
59
|
+
code: "UNAUTHORIZED",
|
|
60
|
+
layer: "controller",
|
|
61
|
+
layerName: "TRPCController",
|
|
62
|
+
}).toTRPC();
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const actor = (0, base_actor_1.createActorFromContext)({ user: ctx.user, session: ctx.session }, "organization");
|
|
66
|
+
return { ...ctx, actor };
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
if (e instanceof errors_1.ServerError)
|
|
70
|
+
throw e.toTRPC();
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function verifyTeamProcedureContext(ctx) {
|
|
40
75
|
if (!ctx.user || !ctx.session) {
|
|
41
76
|
throw new errors_1.ServerError({
|
|
42
77
|
code: "UNAUTHORIZED",
|
|
@@ -44,6 +79,15 @@ function verifyProtectedProcedureContext(ctx) {
|
|
|
44
79
|
layerName: "TRPCController",
|
|
45
80
|
}).toTRPC();
|
|
46
81
|
}
|
|
82
|
+
try {
|
|
83
|
+
const actor = (0, base_actor_1.createActorFromContext)({ user: ctx.user, session: ctx.session }, "team");
|
|
84
|
+
return { ...ctx, actor };
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
if (e instanceof errors_1.ServerError)
|
|
88
|
+
throw e.toTRPC();
|
|
89
|
+
throw e;
|
|
90
|
+
}
|
|
47
91
|
}
|
|
48
92
|
function verifyAdminProcedureContext(ctx) {
|
|
49
93
|
if (!ctx.user || !ctx.session) {
|
|
@@ -60,4 +104,55 @@ function verifyAdminProcedureContext(ctx) {
|
|
|
60
104
|
layerName: "TRPCController",
|
|
61
105
|
}).toTRPC();
|
|
62
106
|
}
|
|
107
|
+
if (!ctx.actor) {
|
|
108
|
+
throw new errors_1.ServerError({
|
|
109
|
+
code: "UNAUTHORIZED",
|
|
110
|
+
layer: "controller",
|
|
111
|
+
layerName: "TRPCController",
|
|
112
|
+
}).toTRPC();
|
|
113
|
+
}
|
|
114
|
+
return ctx;
|
|
115
|
+
}
|
|
116
|
+
function requireRequestUser(ctx) {
|
|
117
|
+
return verifyProtectedProcedureContext(ctx).user;
|
|
118
|
+
}
|
|
119
|
+
function requireRequestActor(ctx, scope = "user") {
|
|
120
|
+
const verified = verifyProtectedProcedureContext(ctx);
|
|
121
|
+
if (scope === "user") {
|
|
122
|
+
if (!(0, base_actor_1.validateActor)(verified.actor, "user")) {
|
|
123
|
+
throw new errors_1.ServerError({
|
|
124
|
+
code: "FORBIDDEN",
|
|
125
|
+
layer: "controller",
|
|
126
|
+
layerName: "TRPCController",
|
|
127
|
+
}).toTRPC();
|
|
128
|
+
}
|
|
129
|
+
return verified.actor;
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
if (scope === "organization") {
|
|
133
|
+
const actor = (0, base_actor_1.createActorFromContext)({ user: verified.user, session: verified.session }, "organization");
|
|
134
|
+
if (!(0, base_actor_1.validateActor)(actor, "organization")) {
|
|
135
|
+
throw new errors_1.ServerError({
|
|
136
|
+
code: "FORBIDDEN",
|
|
137
|
+
layer: "controller",
|
|
138
|
+
layerName: "TRPCController",
|
|
139
|
+
}).toTRPC();
|
|
140
|
+
}
|
|
141
|
+
return actor;
|
|
142
|
+
}
|
|
143
|
+
const actor = (0, base_actor_1.createActorFromContext)({ user: verified.user, session: verified.session }, "team");
|
|
144
|
+
if (!(0, base_actor_1.validateActor)(actor, "team")) {
|
|
145
|
+
throw new errors_1.ServerError({
|
|
146
|
+
code: "FORBIDDEN",
|
|
147
|
+
layer: "controller",
|
|
148
|
+
layerName: "TRPCController",
|
|
149
|
+
}).toTRPC();
|
|
150
|
+
}
|
|
151
|
+
return actor;
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
if (e instanceof errors_1.ServerError)
|
|
155
|
+
throw e.toTRPC();
|
|
156
|
+
throw e;
|
|
157
|
+
}
|
|
63
158
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const server_1 = require("@trpc/server");
|
|
4
|
+
const trpc_1 = require("./trpc");
|
|
5
|
+
jest.mock("better-auth/node", () => ({
|
|
6
|
+
fromNodeHeaders: (headers) => headers,
|
|
7
|
+
}));
|
|
8
|
+
function expectTRPCCode(fn, code) {
|
|
9
|
+
try {
|
|
10
|
+
fn();
|
|
11
|
+
throw new Error(`Expected TRPC error with code ${code}`);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
expect(error).toBeInstanceOf(server_1.TRPCError);
|
|
15
|
+
expect(error.code).toBe(code);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function createUser(overrides = {}) {
|
|
19
|
+
return {
|
|
20
|
+
id: "user-1",
|
|
21
|
+
role: "member",
|
|
22
|
+
email: "user@example.com",
|
|
23
|
+
emailVerified: true,
|
|
24
|
+
name: "User One",
|
|
25
|
+
createdAt: new Date(),
|
|
26
|
+
updatedAt: new Date(),
|
|
27
|
+
onboarding: null,
|
|
28
|
+
preferences: null,
|
|
29
|
+
flags: null,
|
|
30
|
+
stripeCustomerId: null,
|
|
31
|
+
paymentCustomerId: null,
|
|
32
|
+
paymentPlanTier: null,
|
|
33
|
+
paymentPlanExpiresAt: null,
|
|
34
|
+
...overrides,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function createSession(overrides = {}) {
|
|
38
|
+
return {
|
|
39
|
+
id: "session-1",
|
|
40
|
+
userId: "user-1",
|
|
41
|
+
expiresAt: new Date(Date.now() + 60_000),
|
|
42
|
+
createdAt: new Date(),
|
|
43
|
+
updatedAt: new Date(),
|
|
44
|
+
token: "token",
|
|
45
|
+
ipAddress: null,
|
|
46
|
+
userAgent: null,
|
|
47
|
+
activeOrganizationId: null,
|
|
48
|
+
activeOrganizationRole: null,
|
|
49
|
+
activeTeamId: null,
|
|
50
|
+
activeTeamRole: null,
|
|
51
|
+
...overrides,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function createRequestContext(overrides = {}) {
|
|
55
|
+
const user = overrides.user ?? createUser();
|
|
56
|
+
const session = overrides.session ?? createSession();
|
|
57
|
+
const actor = overrides.actor ??
|
|
58
|
+
(user && session
|
|
59
|
+
? {
|
|
60
|
+
userId: user.id,
|
|
61
|
+
userRole: user.role,
|
|
62
|
+
organizationId: session.activeOrganizationId,
|
|
63
|
+
organizationRole: session.activeOrganizationRole,
|
|
64
|
+
teamId: session.activeTeamId,
|
|
65
|
+
teamRole: session.activeTeamRole,
|
|
66
|
+
}
|
|
67
|
+
: null);
|
|
68
|
+
return {
|
|
69
|
+
user,
|
|
70
|
+
session,
|
|
71
|
+
actor,
|
|
72
|
+
...overrides,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
describe("trpc auth helpers", () => {
|
|
76
|
+
it("stores a user-scoped actor on the request context while copying session ids", async () => {
|
|
77
|
+
const user = createUser();
|
|
78
|
+
const session = createSession({
|
|
79
|
+
activeOrganizationId: "org-1",
|
|
80
|
+
activeOrganizationRole: "owner",
|
|
81
|
+
activeTeamId: "team-1",
|
|
82
|
+
activeTeamRole: "manager",
|
|
83
|
+
});
|
|
84
|
+
const auth = {
|
|
85
|
+
api: {
|
|
86
|
+
getSession: jest.fn().mockResolvedValue({ user, session }),
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
const createContext = (0, trpc_1.createAuthContext)(auth);
|
|
90
|
+
const ctx = await createContext({
|
|
91
|
+
req: { headers: {} },
|
|
92
|
+
});
|
|
93
|
+
expect(ctx.actor).toEqual({
|
|
94
|
+
userId: "user-1",
|
|
95
|
+
userRole: "member",
|
|
96
|
+
organizationId: "org-1",
|
|
97
|
+
organizationRole: "owner",
|
|
98
|
+
teamId: "team-1",
|
|
99
|
+
teamRole: "manager",
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
it("throws FORBIDDEN when a broader actor scope is required than the session allows", () => {
|
|
103
|
+
const actor = (0, trpc_1.requireRequestActor)(createRequestContext({
|
|
104
|
+
user: createUser(),
|
|
105
|
+
session: createSession(),
|
|
106
|
+
actor: {
|
|
107
|
+
userId: "user-1",
|
|
108
|
+
userRole: "member",
|
|
109
|
+
organizationId: null,
|
|
110
|
+
organizationRole: null,
|
|
111
|
+
teamId: null,
|
|
112
|
+
teamRole: null,
|
|
113
|
+
},
|
|
114
|
+
}));
|
|
115
|
+
expect(actor.userId).toBe("user-1");
|
|
116
|
+
expectTRPCCode(() => (0, trpc_1.requireRequestActor)(createRequestContext({
|
|
117
|
+
user: createUser(),
|
|
118
|
+
session: createSession(),
|
|
119
|
+
actor: {
|
|
120
|
+
userId: "user-1",
|
|
121
|
+
userRole: "member",
|
|
122
|
+
organizationId: null,
|
|
123
|
+
organizationRole: null,
|
|
124
|
+
teamId: null,
|
|
125
|
+
teamRole: null,
|
|
126
|
+
},
|
|
127
|
+
}), "organization"), "FORBIDDEN");
|
|
128
|
+
});
|
|
129
|
+
it("throws UNAUTHORIZED when request user access is missing", () => {
|
|
130
|
+
expectTRPCCode(() => (0, trpc_1.requireRequestUser)({
|
|
131
|
+
user: null,
|
|
132
|
+
session: null,
|
|
133
|
+
actor: null,
|
|
134
|
+
}), "UNAUTHORIZED");
|
|
135
|
+
});
|
|
136
|
+
it("verifies admin access from the raw request user", () => {
|
|
137
|
+
const ctx = createRequestContext({
|
|
138
|
+
user: createUser({ role: "admin" }),
|
|
139
|
+
actor: {
|
|
140
|
+
userId: "user-1",
|
|
141
|
+
userRole: "admin",
|
|
142
|
+
organizationId: "org-1",
|
|
143
|
+
organizationRole: "owner",
|
|
144
|
+
teamId: null,
|
|
145
|
+
teamRole: null,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
expect((0, trpc_1.verifyAdminProcedureContext)(ctx).user.role).toBe("admin");
|
|
149
|
+
expectTRPCCode(() => (0, trpc_1.verifyAdminProcedureContext)(createRequestContext({
|
|
150
|
+
user: createUser({ role: "member" }),
|
|
151
|
+
actor: ctx.actor,
|
|
152
|
+
})), "FORBIDDEN");
|
|
153
|
+
});
|
|
154
|
+
});
|