@m5kdev/backend 0.6.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 +4 -8
- 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 +1 -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 +17 -20
- package/dist/src/modules/base/base.procedure.js +36 -24
- package/dist/src/modules/base/base.service.d.ts +7 -19
- package/dist/src/modules/base/base.service.js +19 -12
- package/dist/src/modules/base/base.service.test.js +89 -61
- 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.service.d.ts +19 -11
- 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 +36 -6
- package/dist/src/modules/recurrence/recurrence.service.js +13 -10
- package/dist/src/modules/recurrence/recurrence.trpc.d.ts +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.service.d.ts +16 -12
- package/dist/src/modules/tag/tag.service.js +4 -4
- package/dist/src/modules/tag/tag.trpc.d.ts +1 -1
- 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 +4 -4
- 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
|
@@ -6,7 +6,7 @@ import type { OpenRouterProvider } from "@openrouter/ai-sdk-provider";
|
|
|
6
6
|
import { generateText, type ModelMessage } from "ai";
|
|
7
7
|
import type Replicate from "replicate";
|
|
8
8
|
import type { ZodType, z } from "zod";
|
|
9
|
-
import type {
|
|
9
|
+
import type { RequiredServiceActor } from "../base/base.actor";
|
|
10
10
|
import type { ServerResultAsync } from "../base/base.dto";
|
|
11
11
|
import { BaseService } from "../base/base.service";
|
|
12
12
|
import type { AiUsageRepository, AiUsageRow } from "./ai.repository";
|
|
@@ -26,17 +26,20 @@ type GenerateTextInput = {
|
|
|
26
26
|
messages: ModelMessage[];
|
|
27
27
|
prompt?: never;
|
|
28
28
|
};
|
|
29
|
+
type AIServiceActorContext = {
|
|
30
|
+
actor: RequiredServiceActor<"user">;
|
|
31
|
+
};
|
|
29
32
|
type AIServiceGenerateTextParams = Omit<GenerateTextParams, "model" | "prompt" | "messages"> & GenerateTextInput & {
|
|
30
33
|
model: string;
|
|
31
34
|
removeMDash?: boolean;
|
|
32
|
-
ctx?:
|
|
35
|
+
ctx?: AIServiceActorContext;
|
|
33
36
|
};
|
|
34
37
|
type AIServiceGenerateObjectParams<T extends ZodType> = Omit<GenerateTextParams, "model" | "prompt" | "messages" | "output"> & GenerateTextInput & {
|
|
35
38
|
model: string;
|
|
36
39
|
schema: T;
|
|
37
40
|
repairAttempts?: number;
|
|
38
41
|
repairModel?: string;
|
|
39
|
-
ctx?:
|
|
42
|
+
ctx?: AIServiceActorContext;
|
|
40
43
|
};
|
|
41
44
|
export declare class AIService<MastraInstance extends Mastra> extends BaseService<{
|
|
42
45
|
aiUsage?: AiUsageRepository;
|
|
@@ -64,38 +67,33 @@ export declare class AIService<MastraInstance extends Mastra> extends BaseServic
|
|
|
64
67
|
agentUse(agent: string, options: MastraAgentGenerateOptions & {
|
|
65
68
|
prompt?: string;
|
|
66
69
|
messages?: MessageListInput;
|
|
67
|
-
}, ctx?: {
|
|
68
|
-
user: User;
|
|
70
|
+
}, ctx?: AIServiceActorContext & {
|
|
69
71
|
model?: string;
|
|
70
72
|
}): ServerResultAsync<Awaited<ReturnType<MastraModelOutput<any>["getFullOutput"]>>>;
|
|
71
73
|
agentText(agent: string, options: MastraAgentGenerateOptions & {
|
|
72
74
|
prompt?: string;
|
|
73
75
|
messages?: MessageListInput;
|
|
74
|
-
}, ctx?: {
|
|
75
|
-
user: User;
|
|
76
|
+
}, ctx?: AIServiceActorContext & {
|
|
76
77
|
model?: string;
|
|
77
78
|
}): ServerResultAsync<string>;
|
|
78
79
|
agentTextResult(agent: string, options: MastraAgentGenerateOptions & {
|
|
79
80
|
prompt?: string;
|
|
80
81
|
messages?: MessageListInput;
|
|
81
|
-
}, ctx?: {
|
|
82
|
-
user: User;
|
|
82
|
+
}, ctx?: AIServiceActorContext & {
|
|
83
83
|
model?: string;
|
|
84
84
|
}): ServerResultAsync<FullOutput<any>>;
|
|
85
85
|
agentObject<T extends ZodType<any>>(agent: string, options: MastraAgentGenerateOptions & {
|
|
86
86
|
schema: T;
|
|
87
87
|
prompt?: string;
|
|
88
88
|
messages?: MessageListInput;
|
|
89
|
-
}, ctx?: {
|
|
90
|
-
user: User;
|
|
89
|
+
}, ctx?: AIServiceActorContext & {
|
|
91
90
|
model?: string;
|
|
92
91
|
}): ServerResultAsync<z.infer<T>>;
|
|
93
92
|
agentObjectResult<T extends ZodType<any>>(agent: string, options: MastraAgentGenerateOptions & {
|
|
94
93
|
schema: T;
|
|
95
94
|
prompt?: string;
|
|
96
95
|
messages?: MessageListInput;
|
|
97
|
-
}, ctx?: {
|
|
98
|
-
user: User;
|
|
96
|
+
}, ctx?: AIServiceActorContext & {
|
|
99
97
|
model?: string;
|
|
100
98
|
}): ServerResultAsync<FullOutput<any> & {
|
|
101
99
|
object: z.infer<T>;
|
|
@@ -55,8 +55,8 @@ class AIService extends base_service_1.BaseService {
|
|
|
55
55
|
if (!payload)
|
|
56
56
|
return this.error("BAD_REQUEST", "No prompt or messages provided");
|
|
57
57
|
const requestContext = options.requestContext ?? new request_context_1.RequestContext();
|
|
58
|
-
if (ctx?.
|
|
59
|
-
requestContext.set("userId", ctx.
|
|
58
|
+
if (ctx?.actor) {
|
|
59
|
+
requestContext.set("userId", ctx.actor.userId);
|
|
60
60
|
}
|
|
61
61
|
if (ctx?.model) {
|
|
62
62
|
requestContext.set("model", ctx.model);
|
|
@@ -69,7 +69,7 @@ class AIService extends base_service_1.BaseService {
|
|
|
69
69
|
this.logger.info("AGENT USE DONE");
|
|
70
70
|
if (this.repository.aiUsage) {
|
|
71
71
|
const createUsageResult = await this.repository.aiUsage.create({
|
|
72
|
-
userId: ctx?.
|
|
72
|
+
userId: ctx?.actor?.userId,
|
|
73
73
|
model: ctx?.model ?? "unknown",
|
|
74
74
|
provider: "openrouter",
|
|
75
75
|
feature: agent,
|
|
@@ -159,7 +159,7 @@ class AIService extends base_service_1.BaseService {
|
|
|
159
159
|
const result = await (0, ai_1.generateText)(request);
|
|
160
160
|
if (this.repository.aiUsage) {
|
|
161
161
|
const createUsageResult = await this.repository.aiUsage.create({
|
|
162
|
-
userId: ctx?.
|
|
162
|
+
userId: ctx?.actor?.userId,
|
|
163
163
|
model,
|
|
164
164
|
provider: "openrouter",
|
|
165
165
|
feature: "generateText",
|
|
@@ -194,7 +194,7 @@ class AIService extends base_service_1.BaseService {
|
|
|
194
194
|
const result = await (0, ai_1.generateText)(request);
|
|
195
195
|
if (this.repository.aiUsage) {
|
|
196
196
|
const createUsageResult = await this.repository.aiUsage.create({
|
|
197
|
-
userId: ctx?.
|
|
197
|
+
userId: ctx?.actor?.userId,
|
|
198
198
|
model,
|
|
199
199
|
provider: "openrouter",
|
|
200
200
|
feature: "generateObject",
|
|
@@ -213,7 +213,7 @@ class AIService extends base_service_1.BaseService {
|
|
|
213
213
|
if (ai_1.NoObjectGeneratedError.isInstance(error)) {
|
|
214
214
|
if (this.repository.aiUsage) {
|
|
215
215
|
const createUsageResult = await this.repository.aiUsage.create({
|
|
216
|
-
userId: ctx?.
|
|
216
|
+
userId: ctx?.actor?.userId,
|
|
217
217
|
model,
|
|
218
218
|
provider: "openrouter",
|
|
219
219
|
feature: "generateObject",
|
|
@@ -2,7 +2,7 @@ import type { Mastra } from "@mastra/core";
|
|
|
2
2
|
import type { AIService } from "./ai.service";
|
|
3
3
|
import { type TRPCMethods } from "../../utils/trpc";
|
|
4
4
|
export declare function createAITRPC<MastraInstance extends Mastra>({ router, adminProcedure }: TRPCMethods, aiService: AIService<MastraInstance>): import("@trpc/server").TRPCBuiltRouter<{
|
|
5
|
-
ctx: import("
|
|
5
|
+
ctx: import("../../utils/trpc").Context;
|
|
6
6
|
meta: any;
|
|
7
7
|
errorShape: import("@trpc/server").TRPCDefaultErrorShape;
|
|
8
8
|
transformer: true;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type BetterAuthOptions, betterAuth } from "better-auth";
|
|
2
2
|
import { type InferSelectModel } from "drizzle-orm";
|
|
3
3
|
import type { LibSQLDatabase } from "drizzle-orm/libsql";
|
|
4
|
-
import * as auth from "./auth.db";
|
|
5
4
|
import type { BillingService } from "../billing/billing.service";
|
|
6
5
|
import type { EmailService } from "../email/email.service";
|
|
6
|
+
import * as auth from "./auth.db";
|
|
7
7
|
declare const schema: {
|
|
8
8
|
users: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
|
|
9
9
|
name: "users";
|
|
@@ -2345,10 +2345,6 @@ type Schema = typeof schema;
|
|
|
2345
2345
|
export type Orm = LibSQLDatabase<Schema>;
|
|
2346
2346
|
export type User = InferSelectModel<typeof auth.users>;
|
|
2347
2347
|
export type Session = InferSelectModel<typeof auth.sessions>;
|
|
2348
|
-
export type Context = {
|
|
2349
|
-
session: Session;
|
|
2350
|
-
user: User;
|
|
2351
|
-
};
|
|
2352
2348
|
export type BetterAuth = ReturnType<typeof betterAuth>;
|
|
2353
2349
|
type CreateBetterAuthParams<O extends Orm, S extends Schema, E extends EmailService, B extends BillingService> = {
|
|
2354
2350
|
orm: O;
|
|
@@ -3260,13 +3256,13 @@ export declare function createBetterAuth<O extends Orm, S extends Schema, E exte
|
|
|
3260
3256
|
$Infer: {
|
|
3261
3257
|
body: ({
|
|
3262
3258
|
permission: {
|
|
3263
|
-
readonly user?: ("get" | "set-role" | "create" | "
|
|
3259
|
+
readonly user?: ("update" | "get" | "set-role" | "create" | "delete" | "list" | "ban" | "impersonate" | "set-password")[] | undefined;
|
|
3264
3260
|
readonly session?: ("delete" | "list" | "revoke")[] | undefined;
|
|
3265
3261
|
};
|
|
3266
3262
|
permissions?: never | undefined;
|
|
3267
3263
|
} | {
|
|
3268
3264
|
permissions: {
|
|
3269
|
-
readonly user?: ("get" | "set-role" | "create" | "
|
|
3265
|
+
readonly user?: ("update" | "get" | "set-role" | "create" | "delete" | "list" | "ban" | "impersonate" | "set-password")[] | undefined;
|
|
3270
3266
|
readonly session?: ("delete" | "list" | "revoke")[] | undefined;
|
|
3271
3267
|
};
|
|
3272
3268
|
permission?: never | undefined;
|
|
@@ -4811,7 +4807,7 @@ export declare function createBetterAuth<O extends Orm, S extends Schema, E exte
|
|
|
4811
4807
|
} | undefined;
|
|
4812
4808
|
verification?: {
|
|
4813
4809
|
modelName?: string;
|
|
4814
|
-
fields?: Partial<Record<"createdAt" | "updatedAt" | "expiresAt" | "
|
|
4810
|
+
fields?: Partial<Record<"createdAt" | "updatedAt" | "expiresAt" | "identifier" | "value", string>>;
|
|
4815
4811
|
additionalFields?: {
|
|
4816
4812
|
[key: string]: import("better-auth", { with: { "resolution-mode": "import" } }).DBFieldAttribute;
|
|
4817
4813
|
};
|
|
@@ -7,10 +7,10 @@ const drizzle_1 = require("better-auth/adapters/drizzle");
|
|
|
7
7
|
const api_1 = require("better-auth/api");
|
|
8
8
|
const plugins_1 = require("better-auth/plugins");
|
|
9
9
|
const drizzle_orm_1 = require("drizzle-orm");
|
|
10
|
-
const auth = tslib_1.__importStar(require("./auth.db"));
|
|
11
|
-
const auth_utils_1 = require("./auth.utils");
|
|
12
10
|
const logger_1 = require("../../utils/logger");
|
|
13
11
|
const posthog_1 = require("../../utils/posthog");
|
|
12
|
+
const auth = tslib_1.__importStar(require("./auth.db"));
|
|
13
|
+
const auth_utils_1 = require("./auth.utils");
|
|
14
14
|
const schema = { ...auth };
|
|
15
15
|
function createBetterAuth({ orm, schema, services, hooks, options, config }) {
|
|
16
16
|
const { email: emailService, billing: billingService } = services;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import type { Context } from "../../utils/trpc";
|
|
1
2
|
import type { ServerResultAsync } from "../base/base.dto";
|
|
2
3
|
import { BaseService } from "../base/base.service";
|
|
3
4
|
import type { BillingService } from "../billing/billing.service";
|
|
4
5
|
import type { EmailService } from "../email/email.service";
|
|
5
6
|
import type { AccountClaim, AccountClaimMagicLinkOutput, AccountClaimOutput, Waitlist, WaitlistOutput } from "./auth.dto";
|
|
6
|
-
import type { Context, User } from "./auth.lib";
|
|
7
7
|
import type { AuthRepository } from "./auth.repository";
|
|
8
8
|
type AuthServiceDependencies = {
|
|
9
9
|
email: EmailService;
|
|
@@ -15,42 +15,22 @@ export declare class AuthService extends BaseService<{
|
|
|
15
15
|
auth: AuthRepository;
|
|
16
16
|
}, AuthServiceDependencies> {
|
|
17
17
|
private getBillingService;
|
|
18
|
-
private
|
|
19
|
-
getUserWaitlistCount(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}): ServerResultAsync<number>;
|
|
25
|
-
setOnboarding(onboarding: number, { user }: {
|
|
26
|
-
user: User;
|
|
27
|
-
}): ServerResultAsync<number>;
|
|
28
|
-
getPreferences({ user }: {
|
|
29
|
-
user: User;
|
|
30
|
-
}): ServerResultAsync<Record<string, unknown>>;
|
|
31
|
-
setPreferences(preferences: Record<string, unknown>, { user }: {
|
|
32
|
-
user: User;
|
|
33
|
-
}): ServerResultAsync<Record<string, unknown>>;
|
|
18
|
+
private organizationActorFromCtx;
|
|
19
|
+
getUserWaitlistCount(ctx: Context): ServerResultAsync<number>;
|
|
20
|
+
getOnboarding(ctx: Context): ServerResultAsync<number>;
|
|
21
|
+
setOnboarding(onboarding: number, ctx: Context): ServerResultAsync<number>;
|
|
22
|
+
getPreferences(ctx: Context): ServerResultAsync<Record<string, unknown>>;
|
|
23
|
+
setPreferences(preferences: Record<string, unknown>, ctx: Context): ServerResultAsync<Record<string, unknown>>;
|
|
34
24
|
getOrganizationPreferences(ctx: Context): ServerResultAsync<Record<string, unknown>>;
|
|
35
25
|
setOrganizationPreferences(preferences: Record<string, unknown>, ctx: Context): ServerResultAsync<Record<string, unknown>>;
|
|
36
|
-
getMetadata(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
setMetadata(metadata: Record<string, unknown>, { user }: {
|
|
40
|
-
user: User;
|
|
41
|
-
}): ServerResultAsync<Record<string, unknown>>;
|
|
42
|
-
getFlags({ user }: {
|
|
43
|
-
user: User;
|
|
44
|
-
}): ServerResultAsync<string[]>;
|
|
26
|
+
getMetadata(ctx: Context): ServerResultAsync<Record<string, unknown>>;
|
|
27
|
+
setMetadata(metadata: Record<string, unknown>, ctx: Context): ServerResultAsync<Record<string, unknown>>;
|
|
28
|
+
getFlags(ctx: Context): ServerResultAsync<string[]>;
|
|
45
29
|
getOrganizationFlags(ctx: Context): ServerResultAsync<string[]>;
|
|
46
|
-
setFlags(flags: string[],
|
|
47
|
-
user: User;
|
|
48
|
-
}): ServerResultAsync<string[]>;
|
|
30
|
+
setFlags(flags: string[], ctx: Context): ServerResultAsync<string[]>;
|
|
49
31
|
setOrganizationFlags(flags: string[], ctx: Context): ServerResultAsync<string[]>;
|
|
50
32
|
listAdminWaitlist(): ServerResultAsync<WaitlistOutput[]>;
|
|
51
|
-
listWaitlist(
|
|
52
|
-
user: User;
|
|
53
|
-
}): ServerResultAsync<Waitlist[]>;
|
|
33
|
+
listWaitlist(ctx: Context): ServerResultAsync<Waitlist[]>;
|
|
54
34
|
addToWaitlist({ email }: {
|
|
55
35
|
email: string;
|
|
56
36
|
}): ServerResultAsync<WaitlistOutput>;
|
|
@@ -60,14 +40,10 @@ export declare class AuthService extends BaseService<{
|
|
|
60
40
|
inviteToWaitlist({ email, name }: {
|
|
61
41
|
email: string;
|
|
62
42
|
name?: string;
|
|
63
|
-
},
|
|
64
|
-
user: User;
|
|
65
|
-
}): ServerResultAsync<Waitlist>;
|
|
43
|
+
}, ctx: Context): ServerResultAsync<Waitlist>;
|
|
66
44
|
createInvitationCode({ name }: {
|
|
67
45
|
name?: string;
|
|
68
|
-
},
|
|
69
|
-
user: User;
|
|
70
|
-
}): ServerResultAsync<Waitlist>;
|
|
46
|
+
}, ctx: Context): ServerResultAsync<Waitlist>;
|
|
71
47
|
joinWaitlist({ email }: {
|
|
72
48
|
email: string;
|
|
73
49
|
}): ServerResultAsync<WaitlistOutput>;
|
|
@@ -82,19 +58,13 @@ export declare class AuthService extends BaseService<{
|
|
|
82
58
|
expiresInHours?: number;
|
|
83
59
|
}): ServerResultAsync<AccountClaim>;
|
|
84
60
|
listAccountClaims(): ServerResultAsync<AccountClaimOutput[]>;
|
|
85
|
-
getMyAccountClaimStatus(
|
|
86
|
-
user: User;
|
|
87
|
-
}): ServerResultAsync<AccountClaim | null>;
|
|
61
|
+
getMyAccountClaimStatus(ctx: Context): ServerResultAsync<AccountClaim | null>;
|
|
88
62
|
setMyAccountClaimEmail({ email }: {
|
|
89
63
|
email: string;
|
|
90
|
-
},
|
|
91
|
-
user: User;
|
|
92
|
-
}): ServerResultAsync<{
|
|
64
|
+
}, ctx: Context): ServerResultAsync<{
|
|
93
65
|
status: boolean;
|
|
94
66
|
}>;
|
|
95
|
-
acceptMyAccountClaim(
|
|
96
|
-
user: User;
|
|
97
|
-
}): ServerResultAsync<{
|
|
67
|
+
acceptMyAccountClaim(ctx: Context): ServerResultAsync<{
|
|
98
68
|
status: boolean;
|
|
99
69
|
}>;
|
|
100
70
|
generateAccountClaimMagicLink({ claimId, email, }: {
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AuthService = void 0;
|
|
4
4
|
const neverthrow_1 = require("neverthrow");
|
|
5
5
|
const posthog_1 = require("../../utils/posthog");
|
|
6
|
+
const errors_1 = require("../../utils/errors");
|
|
7
|
+
const base_actor_1 = require("../base/base.actor");
|
|
6
8
|
const base_service_1 = require("../base/base.service");
|
|
7
9
|
class AuthService extends base_service_1.BaseService {
|
|
8
10
|
getBillingService() {
|
|
@@ -10,104 +12,111 @@ class AuthService extends base_service_1.BaseService {
|
|
|
10
12
|
return null;
|
|
11
13
|
return this.service.billing;
|
|
12
14
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
organizationActorFromCtx(ctx) {
|
|
16
|
+
try {
|
|
17
|
+
return (0, neverthrow_1.ok)((0, base_actor_1.createActorFromContext)({ user: ctx.user, session: ctx.session }, "organization"));
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
if (e instanceof errors_1.ServerError)
|
|
21
|
+
return (0, neverthrow_1.err)(e);
|
|
22
|
+
throw e;
|
|
17
23
|
}
|
|
18
|
-
return (0, neverthrow_1.ok)(organizationId);
|
|
19
24
|
}
|
|
20
|
-
async getUserWaitlistCount(
|
|
21
|
-
if (
|
|
25
|
+
async getUserWaitlistCount(ctx) {
|
|
26
|
+
if (ctx.actor.userRole === "admin")
|
|
22
27
|
return (0, neverthrow_1.ok)(0);
|
|
23
|
-
return this.repository.auth.getUserWaitlistCount(
|
|
28
|
+
return this.repository.auth.getUserWaitlistCount(ctx.actor.userId);
|
|
24
29
|
}
|
|
25
|
-
async getOnboarding(
|
|
26
|
-
return this.repository.auth.getOnboarding(
|
|
30
|
+
async getOnboarding(ctx) {
|
|
31
|
+
return this.repository.auth.getOnboarding(ctx.actor.userId);
|
|
27
32
|
}
|
|
28
|
-
async setOnboarding(onboarding,
|
|
33
|
+
async setOnboarding(onboarding, ctx) {
|
|
29
34
|
(0, posthog_1.posthogCapture)({
|
|
30
|
-
distinctId:
|
|
35
|
+
distinctId: ctx.actor.userId,
|
|
31
36
|
event: "onboarding_set",
|
|
32
37
|
properties: {
|
|
33
38
|
onboarding,
|
|
34
39
|
},
|
|
35
40
|
});
|
|
36
|
-
return this.repository.auth.setOnboarding(
|
|
41
|
+
return this.repository.auth.setOnboarding(ctx.actor.userId, onboarding);
|
|
37
42
|
}
|
|
38
|
-
async getPreferences(
|
|
39
|
-
return this.repository.auth.getPreferences(
|
|
43
|
+
async getPreferences(ctx) {
|
|
44
|
+
return this.repository.auth.getPreferences(ctx.actor.userId);
|
|
40
45
|
}
|
|
41
|
-
async setPreferences(preferences,
|
|
46
|
+
async setPreferences(preferences, ctx) {
|
|
42
47
|
(0, posthog_1.posthogCapture)({
|
|
43
|
-
distinctId:
|
|
48
|
+
distinctId: ctx.actor.userId,
|
|
44
49
|
event: "preferences_set",
|
|
45
50
|
});
|
|
46
|
-
return this.repository.auth.setPreferences(
|
|
51
|
+
return this.repository.auth.setPreferences(ctx.actor.userId, preferences);
|
|
47
52
|
}
|
|
48
53
|
async getOrganizationPreferences(ctx) {
|
|
49
|
-
const
|
|
50
|
-
if (
|
|
51
|
-
return (0, neverthrow_1.err)(
|
|
52
|
-
|
|
54
|
+
const org = this.organizationActorFromCtx(ctx);
|
|
55
|
+
if (org.isErr())
|
|
56
|
+
return (0, neverthrow_1.err)(org.error);
|
|
57
|
+
const actor = org.value;
|
|
58
|
+
return this.repository.auth.getOrganizationPreferences(actor.userId, actor.organizationId);
|
|
53
59
|
}
|
|
54
60
|
async setOrganizationPreferences(preferences, ctx) {
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
return (0, neverthrow_1.err)(
|
|
61
|
+
const org = this.organizationActorFromCtx(ctx);
|
|
62
|
+
if (org.isErr())
|
|
63
|
+
return (0, neverthrow_1.err)(org.error);
|
|
64
|
+
const actor = org.value;
|
|
58
65
|
(0, posthog_1.posthogCapture)({
|
|
59
|
-
distinctId:
|
|
66
|
+
distinctId: actor.userId,
|
|
60
67
|
event: "organization_preferences_set",
|
|
61
68
|
properties: {
|
|
62
|
-
organizationId: organizationId
|
|
69
|
+
organizationId: actor.organizationId,
|
|
63
70
|
},
|
|
64
71
|
});
|
|
65
|
-
return this.repository.auth.setOrganizationPreferences(
|
|
72
|
+
return this.repository.auth.setOrganizationPreferences(actor.userId, actor.organizationId, preferences);
|
|
66
73
|
}
|
|
67
|
-
async getMetadata(
|
|
68
|
-
return this.repository.auth.getMetadata(
|
|
74
|
+
async getMetadata(ctx) {
|
|
75
|
+
return this.repository.auth.getMetadata(ctx.actor.userId);
|
|
69
76
|
}
|
|
70
|
-
async setMetadata(metadata,
|
|
77
|
+
async setMetadata(metadata, ctx) {
|
|
71
78
|
(0, posthog_1.posthogCapture)({
|
|
72
|
-
distinctId:
|
|
79
|
+
distinctId: ctx.actor.userId,
|
|
73
80
|
event: "metadata_set",
|
|
74
81
|
});
|
|
75
|
-
return this.repository.auth.setMetadata(
|
|
82
|
+
return this.repository.auth.setMetadata(ctx.actor.userId, metadata);
|
|
76
83
|
}
|
|
77
|
-
async getFlags(
|
|
78
|
-
return this.repository.auth.getFlags(
|
|
84
|
+
async getFlags(ctx) {
|
|
85
|
+
return this.repository.auth.getFlags(ctx.actor.userId);
|
|
79
86
|
}
|
|
80
87
|
async getOrganizationFlags(ctx) {
|
|
81
|
-
const
|
|
82
|
-
if (
|
|
83
|
-
return (0, neverthrow_1.err)(
|
|
84
|
-
|
|
88
|
+
const org = this.organizationActorFromCtx(ctx);
|
|
89
|
+
if (org.isErr())
|
|
90
|
+
return (0, neverthrow_1.err)(org.error);
|
|
91
|
+
const actor = org.value;
|
|
92
|
+
return this.repository.auth.getOrganizationFlags(actor.userId, actor.organizationId);
|
|
85
93
|
}
|
|
86
|
-
async setFlags(flags,
|
|
94
|
+
async setFlags(flags, ctx) {
|
|
87
95
|
(0, posthog_1.posthogCapture)({
|
|
88
|
-
distinctId:
|
|
96
|
+
distinctId: ctx.actor.userId,
|
|
89
97
|
event: "flags_set",
|
|
90
98
|
});
|
|
91
|
-
return this.repository.auth.setFlags(
|
|
99
|
+
return this.repository.auth.setFlags(ctx.actor.userId, flags);
|
|
92
100
|
}
|
|
93
101
|
async setOrganizationFlags(flags, ctx) {
|
|
94
|
-
const
|
|
95
|
-
if (
|
|
96
|
-
return (0, neverthrow_1.err)(
|
|
102
|
+
const org = this.organizationActorFromCtx(ctx);
|
|
103
|
+
if (org.isErr())
|
|
104
|
+
return (0, neverthrow_1.err)(org.error);
|
|
105
|
+
const actor = org.value;
|
|
97
106
|
(0, posthog_1.posthogCapture)({
|
|
98
|
-
distinctId:
|
|
107
|
+
distinctId: actor.userId,
|
|
99
108
|
event: "organization_flags_set",
|
|
100
109
|
properties: {
|
|
101
|
-
organizationId: organizationId
|
|
110
|
+
organizationId: actor.organizationId,
|
|
102
111
|
},
|
|
103
112
|
});
|
|
104
|
-
return this.repository.auth.setOrganizationFlags(
|
|
113
|
+
return this.repository.auth.setOrganizationFlags(actor.userId, actor.organizationId, flags);
|
|
105
114
|
}
|
|
106
115
|
async listAdminWaitlist() {
|
|
107
116
|
return this.repository.auth.listAdminWaitlist();
|
|
108
117
|
}
|
|
109
|
-
async listWaitlist(
|
|
110
|
-
return this.repository.auth.listWaitlist(
|
|
118
|
+
async listWaitlist(ctx) {
|
|
119
|
+
return this.repository.auth.listWaitlist(ctx.actor.userId);
|
|
111
120
|
}
|
|
112
121
|
async addToWaitlist({ email }) {
|
|
113
122
|
return this.repository.auth.addToWaitlist(email);
|
|
@@ -123,20 +132,24 @@ class AuthService extends base_service_1.BaseService {
|
|
|
123
132
|
await this.service.email.sendWaitlistInvite(waitlist.value.email, waitlist.value.code);
|
|
124
133
|
return (0, neverthrow_1.ok)(waitlist.value);
|
|
125
134
|
}
|
|
126
|
-
async inviteToWaitlist({ email, name },
|
|
127
|
-
const count = await this.repository.auth.getUserWaitlistCount(user.id);
|
|
135
|
+
async inviteToWaitlist({ email, name }, ctx) {
|
|
136
|
+
const count = await this.repository.auth.getUserWaitlistCount(ctx.user.id);
|
|
128
137
|
if (count.isErr())
|
|
129
138
|
return (0, neverthrow_1.err)(count.error);
|
|
130
139
|
if (count.value >= 3)
|
|
131
140
|
return this.repository.auth.error("BAD_REQUEST", "Run out of invites");
|
|
132
|
-
const waitlist = await this.repository.auth.inviteToWaitlist({
|
|
141
|
+
const waitlist = await this.repository.auth.inviteToWaitlist({
|
|
142
|
+
email,
|
|
143
|
+
userId: ctx.user.id,
|
|
144
|
+
name,
|
|
145
|
+
});
|
|
133
146
|
if (waitlist.isErr())
|
|
134
147
|
return (0, neverthrow_1.err)(waitlist.error);
|
|
135
148
|
if (!waitlist.value.code)
|
|
136
149
|
return this.repository.auth.error("BAD_REQUEST");
|
|
137
|
-
await this.service.email.sendWaitlistUserInvite(email, waitlist.value.code, user.name, name);
|
|
150
|
+
await this.service.email.sendWaitlistUserInvite(email, waitlist.value.code, ctx.user.name, name);
|
|
138
151
|
(0, posthog_1.posthogCapture)({
|
|
139
|
-
distinctId: user.id,
|
|
152
|
+
distinctId: ctx.user.id,
|
|
140
153
|
event: "waitlist_invite_sent",
|
|
141
154
|
properties: {
|
|
142
155
|
email,
|
|
@@ -145,15 +158,15 @@ class AuthService extends base_service_1.BaseService {
|
|
|
145
158
|
});
|
|
146
159
|
return (0, neverthrow_1.ok)(waitlist.value);
|
|
147
160
|
}
|
|
148
|
-
async createInvitationCode({ name },
|
|
161
|
+
async createInvitationCode({ name }, ctx) {
|
|
149
162
|
(0, posthog_1.posthogCapture)({
|
|
150
|
-
distinctId:
|
|
163
|
+
distinctId: ctx.actor.userId,
|
|
151
164
|
event: "waitlist_invitation_code_created",
|
|
152
165
|
properties: {
|
|
153
166
|
name,
|
|
154
167
|
},
|
|
155
168
|
});
|
|
156
|
-
return this.repository.auth.createInvitationCode({ userId:
|
|
169
|
+
return this.repository.auth.createInvitationCode({ userId: ctx.actor.userId, name });
|
|
157
170
|
}
|
|
158
171
|
async joinWaitlist({ email }) {
|
|
159
172
|
const waitlist = await this.repository.auth.joinWaitlist(email);
|
|
@@ -174,23 +187,23 @@ class AuthService extends base_service_1.BaseService {
|
|
|
174
187
|
async listAccountClaims() {
|
|
175
188
|
return this.repository.auth.listAccountClaims();
|
|
176
189
|
}
|
|
177
|
-
async getMyAccountClaimStatus(
|
|
178
|
-
return this.repository.auth.findPendingAccountClaimForUser(
|
|
190
|
+
async getMyAccountClaimStatus(ctx) {
|
|
191
|
+
return this.repository.auth.findPendingAccountClaimForUser(ctx.actor.userId);
|
|
179
192
|
}
|
|
180
|
-
async setMyAccountClaimEmail({ email },
|
|
181
|
-
return this.repository.auth.setAccountClaimEmail({ userId:
|
|
193
|
+
async setMyAccountClaimEmail({ email }, ctx) {
|
|
194
|
+
return this.repository.auth.setAccountClaimEmail({ userId: ctx.actor.userId, email });
|
|
182
195
|
}
|
|
183
|
-
async acceptMyAccountClaim(
|
|
184
|
-
const pendingClaim = await this.repository.auth.findPendingAccountClaimForUser(user.id);
|
|
196
|
+
async acceptMyAccountClaim(ctx) {
|
|
197
|
+
const pendingClaim = await this.repository.auth.findPendingAccountClaimForUser(ctx.user.id);
|
|
185
198
|
if (pendingClaim.isErr())
|
|
186
199
|
return (0, neverthrow_1.err)(pendingClaim.error);
|
|
187
|
-
const accepted = await this.repository.auth.acceptAccountClaim(user.id);
|
|
200
|
+
const accepted = await this.repository.auth.acceptAccountClaim(ctx.user.id);
|
|
188
201
|
if (accepted.isErr())
|
|
189
202
|
return (0, neverthrow_1.err)(accepted.error);
|
|
190
203
|
if (pendingClaim.value) {
|
|
191
204
|
const billingService = this.getBillingService();
|
|
192
205
|
if (billingService) {
|
|
193
|
-
await billingService.createUserHook({ user });
|
|
206
|
+
await billingService.createUserHook({ user: ctx.user });
|
|
194
207
|
}
|
|
195
208
|
}
|
|
196
209
|
return (0, neverthrow_1.ok)(accepted.value);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type TRPCMethods } from "../../utils/trpc";
|
|
2
2
|
import type { AuthService } from "./auth.service";
|
|
3
3
|
export declare function createAuthTRPC({ router, publicProcedure, privateProcedure: procedure, adminProcedure }: TRPCMethods, authService: AuthService): import("@trpc/server").TRPCBuiltRouter<{
|
|
4
|
-
ctx: import("
|
|
4
|
+
ctx: import("../../utils/trpc").Context;
|
|
5
5
|
meta: any;
|
|
6
6
|
errorShape: import("@trpc/server").TRPCDefaultErrorShape;
|
|
7
7
|
transformer: true;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Session, User } from "../auth/auth.lib";
|
|
2
|
+
export type UserActor = {
|
|
3
|
+
userId: string;
|
|
4
|
+
userRole: string;
|
|
5
|
+
organizationId: string | null;
|
|
6
|
+
organizationRole: string | null;
|
|
7
|
+
teamId: string | null;
|
|
8
|
+
teamRole: string | null;
|
|
9
|
+
};
|
|
10
|
+
export type OrganizationActor = {
|
|
11
|
+
userId: string;
|
|
12
|
+
userRole: string;
|
|
13
|
+
organizationId: string;
|
|
14
|
+
organizationRole: string;
|
|
15
|
+
teamId: string | null;
|
|
16
|
+
teamRole: string | null;
|
|
17
|
+
};
|
|
18
|
+
export type TeamActor = {
|
|
19
|
+
userId: string;
|
|
20
|
+
userRole: string;
|
|
21
|
+
organizationId: string;
|
|
22
|
+
organizationRole: string;
|
|
23
|
+
teamId: string;
|
|
24
|
+
teamRole: string;
|
|
25
|
+
};
|
|
26
|
+
export type AuthenticatedActor = UserActor | OrganizationActor | TeamActor;
|
|
27
|
+
/** @deprecated Prefer `AuthenticatedActor` — kept for grants and legacy call sites */
|
|
28
|
+
export type ServiceActor = AuthenticatedActor;
|
|
29
|
+
export type Actor = {
|
|
30
|
+
user: UserActor;
|
|
31
|
+
organization: OrganizationActor;
|
|
32
|
+
team: TeamActor;
|
|
33
|
+
authenticated: AuthenticatedActor;
|
|
34
|
+
};
|
|
35
|
+
export type ActorScope = "user" | "organization" | "team";
|
|
36
|
+
export type RequiredServiceActor<Scope extends ActorScope> = Actor[Scope];
|
|
37
|
+
/** Claims shape used by tests and factories */
|
|
38
|
+
export type ServiceActorClaims = {
|
|
39
|
+
userId: string;
|
|
40
|
+
userRole: string;
|
|
41
|
+
organizationId?: string | null;
|
|
42
|
+
organizationRole?: string | null;
|
|
43
|
+
teamId?: string | null;
|
|
44
|
+
teamRole?: string | null;
|
|
45
|
+
};
|
|
46
|
+
/** @deprecated Prefer `OrganizationActor` */
|
|
47
|
+
export type ServiceOrganizationActor = OrganizationActor;
|
|
48
|
+
/** @deprecated Prefer `TeamActor` */
|
|
49
|
+
export type ServiceTeamActor = TeamActor;
|
|
50
|
+
export declare function createActorFromContext(context: {
|
|
51
|
+
user: User;
|
|
52
|
+
session: Session;
|
|
53
|
+
}, scope: "team"): TeamActor;
|
|
54
|
+
export declare function createActorFromContext(context: {
|
|
55
|
+
user: User;
|
|
56
|
+
session: Session;
|
|
57
|
+
}, scope: "organization"): OrganizationActor;
|
|
58
|
+
export declare function createActorFromContext(context: {
|
|
59
|
+
user: User;
|
|
60
|
+
session: Session;
|
|
61
|
+
}, scope: "user"): UserActor;
|
|
62
|
+
export declare function validateActor(actor: AuthenticatedActor, scope: ActorScope): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Builds a flat actor for tests / grants without session. Validates that team scope implies organization.
|
|
65
|
+
*/
|
|
66
|
+
export declare function createServiceActor(claims: ServiceActorClaims): AuthenticatedActor;
|
|
67
|
+
export declare function getServiceActorScope(actor: AuthenticatedActor): ActorScope;
|
|
68
|
+
export declare function hasServiceActorScope(actor: AuthenticatedActor, scope: ActorScope): boolean;
|