@robelest/convex-auth 0.0.2-preview.1 → 0.0.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/dist/bin.cjs +466 -63
- package/dist/client/index.d.ts +211 -30
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +673 -59
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +56 -1
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +93 -3
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/convex.config.d.ts.map +1 -1
- package/dist/component/convex.config.js +2 -0
- package/dist/component/convex.config.js.map +1 -1
- package/dist/component/index.d.ts +5 -3
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/index.js +5 -3
- package/dist/component/index.js.map +1 -1
- package/dist/component/portalBridge.d.ts +80 -0
- package/dist/component/portalBridge.d.ts.map +1 -0
- package/dist/component/portalBridge.js +102 -0
- package/dist/component/portalBridge.js.map +1 -0
- package/dist/component/public.d.ts +193 -9
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +204 -33
- package/dist/component/public.js.map +1 -1
- package/dist/component/schema.d.ts +89 -9
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +68 -7
- package/dist/component/schema.js.map +1 -1
- package/dist/providers/{Anonymous.d.ts → anonymous.d.ts} +8 -8
- package/dist/providers/{Anonymous.d.ts.map → anonymous.d.ts.map} +1 -1
- package/dist/providers/{Anonymous.js → anonymous.js} +9 -10
- package/dist/providers/anonymous.js.map +1 -0
- package/dist/providers/{ConvexCredentials.d.ts → credentials.d.ts} +11 -11
- package/dist/providers/credentials.d.ts.map +1 -0
- package/dist/providers/{ConvexCredentials.js → credentials.js} +8 -8
- package/dist/providers/credentials.js.map +1 -0
- package/dist/providers/{Email.d.ts → email.d.ts} +6 -6
- package/dist/providers/email.d.ts.map +1 -0
- package/dist/providers/{Email.js → email.js} +6 -6
- package/dist/providers/email.js.map +1 -0
- package/dist/providers/passkey.d.ts +20 -0
- package/dist/providers/passkey.d.ts.map +1 -0
- package/dist/providers/passkey.js +32 -0
- package/dist/providers/passkey.js.map +1 -0
- package/dist/providers/{Password.d.ts → password.d.ts} +10 -10
- package/dist/providers/{Password.d.ts.map → password.d.ts.map} +1 -1
- package/dist/providers/{Password.js → password.js} +19 -20
- package/dist/providers/password.js.map +1 -0
- package/dist/providers/{Phone.d.ts → phone.d.ts} +3 -3
- package/dist/providers/{Phone.d.ts.map → phone.d.ts.map} +1 -1
- package/dist/providers/{Phone.js → phone.js} +3 -3
- package/dist/providers/{Phone.js.map → phone.js.map} +1 -1
- package/dist/providers/totp.d.ts +14 -0
- package/dist/providers/totp.d.ts.map +1 -0
- package/dist/providers/totp.js +23 -0
- package/dist/providers/totp.js.map +1 -0
- package/dist/server/convex-auth.d.ts +243 -0
- package/dist/server/convex-auth.d.ts.map +1 -0
- package/dist/server/convex-auth.js +365 -0
- package/dist/server/convex-auth.js.map +1 -0
- package/dist/server/implementation/index.d.ts +153 -166
- package/dist/server/implementation/index.d.ts.map +1 -1
- package/dist/server/implementation/index.js +162 -105
- package/dist/server/implementation/index.js.map +1 -1
- package/dist/server/implementation/passkey.d.ts +33 -0
- package/dist/server/implementation/passkey.d.ts.map +1 -0
- package/dist/server/implementation/passkey.js +450 -0
- package/dist/server/implementation/passkey.js.map +1 -0
- package/dist/server/implementation/redirects.d.ts.map +1 -1
- package/dist/server/implementation/redirects.js +4 -9
- package/dist/server/implementation/redirects.js.map +1 -1
- package/dist/server/implementation/sessions.d.ts +2 -20
- package/dist/server/implementation/sessions.d.ts.map +1 -1
- package/dist/server/implementation/sessions.js +2 -20
- package/dist/server/implementation/sessions.js.map +1 -1
- package/dist/server/implementation/signIn.d.ts +13 -0
- package/dist/server/implementation/signIn.d.ts.map +1 -1
- package/dist/server/implementation/signIn.js +26 -1
- package/dist/server/implementation/signIn.js.map +1 -1
- package/dist/server/implementation/totp.d.ts +40 -0
- package/dist/server/implementation/totp.d.ts.map +1 -0
- package/dist/server/implementation/totp.js +211 -0
- package/dist/server/implementation/totp.js.map +1 -0
- package/dist/server/index.d.ts +18 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +255 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/portal-email.d.ts +19 -0
- package/dist/server/portal-email.d.ts.map +1 -0
- package/dist/server/portal-email.js +89 -0
- package/dist/server/portal-email.js.map +1 -0
- package/dist/server/portal.d.ts +116 -0
- package/dist/server/portal.d.ts.map +1 -0
- package/dist/server/portal.js +294 -0
- package/dist/server/portal.js.map +1 -0
- package/dist/server/provider_utils.d.ts +1 -1
- package/dist/server/provider_utils.d.ts.map +1 -1
- package/dist/server/provider_utils.js +39 -1
- package/dist/server/provider_utils.js.map +1 -1
- package/dist/server/types.d.ts +128 -11
- package/dist/server/types.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/cli/index.ts +48 -6
- package/src/cli/portal-link.ts +112 -0
- package/src/cli/portal-upload.ts +411 -0
- package/src/client/index.ts +823 -109
- package/src/component/_generated/api.ts +72 -1
- package/src/component/_generated/component.ts +180 -4
- package/src/component/convex.config.ts +3 -0
- package/src/component/index.ts +5 -10
- package/src/component/portalBridge.ts +116 -0
- package/src/component/public.ts +231 -37
- package/src/component/schema.ts +70 -7
- package/src/providers/{Anonymous.ts → anonymous.ts} +10 -11
- package/src/providers/{ConvexCredentials.ts → credentials.ts} +11 -11
- package/src/providers/{Email.ts → email.ts} +5 -5
- package/src/providers/passkey.ts +35 -0
- package/src/providers/{Password.ts → password.ts} +22 -27
- package/src/providers/{Phone.ts → phone.ts} +2 -2
- package/src/providers/totp.ts +26 -0
- package/src/server/convex-auth.ts +470 -0
- package/src/server/implementation/index.ts +228 -239
- package/src/server/implementation/passkey.ts +650 -0
- package/src/server/implementation/redirects.ts +4 -11
- package/src/server/implementation/sessions.ts +2 -20
- package/src/server/implementation/signIn.ts +39 -1
- package/src/server/implementation/totp.ts +366 -0
- package/src/server/index.ts +373 -0
- package/src/server/portal-email.ts +95 -0
- package/src/server/portal.ts +375 -0
- package/src/server/provider_utils.ts +42 -1
- package/src/server/types.ts +161 -10
- package/dist/providers/Anonymous.js.map +0 -1
- package/dist/providers/ConvexCredentials.d.ts.map +0 -1
- package/dist/providers/ConvexCredentials.js.map +0 -1
- package/dist/providers/Email.d.ts.map +0 -1
- package/dist/providers/Email.js.map +0 -1
- package/dist/providers/Password.js.map +0 -1
- package/providers/Anonymous/package.json +0 -6
- package/providers/ConvexCredentials/package.json +0 -6
- package/providers/Email/package.json +0 -6
- package/providers/Password/package.json +0 -6
- package/providers/Phone/package.json +0 -6
- package/server/package.json +0 -6
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `Auth` class — the main entry point for Convex Auth.
|
|
3
|
+
*
|
|
4
|
+
* Combines authentication and portal admin functionality:
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* // convex/auth.ts
|
|
8
|
+
* import { Auth, Portal } from "@robelest/convex-auth/component";
|
|
9
|
+
* import github from "@auth/core/providers/github";
|
|
10
|
+
* import { components } from "./_generated/api";
|
|
11
|
+
*
|
|
12
|
+
* export const auth = new Auth(components.auth, {
|
|
13
|
+
* providers: [github],
|
|
14
|
+
* });
|
|
15
|
+
* export const { signIn, signOut, store } = auth;
|
|
16
|
+
* export const { portalQuery, portalMutation, portalInternal } = Portal(auth);
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import { queryGeneric, mutationGeneric, internalMutationGeneric, } from "convex/server";
|
|
22
|
+
import { v } from "convex/values";
|
|
23
|
+
import { Auth as AuthFactory } from "./implementation/index.js";
|
|
24
|
+
import { registerStaticRoutes } from "@convex-dev/self-hosting";
|
|
25
|
+
import { portalMagicLinkEmail } from "./portal-email.js";
|
|
26
|
+
import email from "../providers/email.js";
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// Helpers
|
|
29
|
+
// ============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* Check if the authenticated user is a portal admin.
|
|
32
|
+
* Uses the new index `roleAndStatusAndAcceptedByUserId` for efficient lookup.
|
|
33
|
+
*/
|
|
34
|
+
async function requirePortalAdmin(ctx, authComponent, userId) {
|
|
35
|
+
// Use inviteList with status filter, then check role + userId in-memory.
|
|
36
|
+
// The new index makes the status filter efficient.
|
|
37
|
+
const invites = await ctx.runQuery(authComponent.public.inviteList, {
|
|
38
|
+
status: "accepted",
|
|
39
|
+
});
|
|
40
|
+
const isAdmin = invites.some((invite) => invite.role === "portalAdmin" && invite.acceptedByUserId === userId);
|
|
41
|
+
if (!isAdmin) {
|
|
42
|
+
throw new Error("Not authorized: portal admin access required");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Auth class
|
|
47
|
+
// ============================================================================
|
|
48
|
+
/**
|
|
49
|
+
* Main entry point for Convex Auth. Instantiate with your component
|
|
50
|
+
* reference and config to get all the exports you need.
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* export const auth = new Auth(components.auth, {
|
|
54
|
+
* providers: [github, resend({ ... })],
|
|
55
|
+
* });
|
|
56
|
+
* export const { signIn, signOut, store } = auth;
|
|
57
|
+
* export const { portalQuery, portalMutation, portalInternal } = Portal(auth);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export class Auth {
|
|
61
|
+
/** The inner `auth` helper object from AuthFactory() */
|
|
62
|
+
_auth;
|
|
63
|
+
/** The signIn action — export this from your convex/auth.ts */
|
|
64
|
+
signIn;
|
|
65
|
+
/** The signOut action — export this from your convex/auth.ts */
|
|
66
|
+
signOut;
|
|
67
|
+
/** The store internal mutation — export this from your convex/auth.ts */
|
|
68
|
+
store;
|
|
69
|
+
/** @internal */
|
|
70
|
+
component;
|
|
71
|
+
/** @internal */
|
|
72
|
+
portalUrl;
|
|
73
|
+
// ---- Proxied auth helper sub-objects ----
|
|
74
|
+
/** User helpers: `.current(ctx)`, `.require(ctx)`, `.get(ctx, userId)`, `.viewer(ctx)` */
|
|
75
|
+
get user() { return this._auth.user; }
|
|
76
|
+
/** Session helpers */
|
|
77
|
+
get session() { return this._auth.session; }
|
|
78
|
+
/** Provider helpers */
|
|
79
|
+
get provider() { return this._auth.provider; }
|
|
80
|
+
/** Account helpers */
|
|
81
|
+
get account() { return this._auth.account; }
|
|
82
|
+
/** Group helpers */
|
|
83
|
+
get group() { return this._auth.group; }
|
|
84
|
+
/** Invite helpers */
|
|
85
|
+
get invite() { return this._auth.invite; }
|
|
86
|
+
/** Passkey helpers */
|
|
87
|
+
get passkey() { return this._auth.passkey; }
|
|
88
|
+
/** TOTP helpers */
|
|
89
|
+
get totp() { return this._auth.totp; }
|
|
90
|
+
constructor(component, config) {
|
|
91
|
+
this.component = component;
|
|
92
|
+
// Derive portal URL from CONVEX_SITE_URL
|
|
93
|
+
this.portalUrl = process.env.CONVEX_SITE_URL
|
|
94
|
+
? `${process.env.CONVEX_SITE_URL.replace(/\/$/, "")}/auth`
|
|
95
|
+
: "/auth";
|
|
96
|
+
// Auto-register the `portal` email provider for magic link sign-in
|
|
97
|
+
const providers = [...config.providers];
|
|
98
|
+
providers.push(email({
|
|
99
|
+
id: "portal",
|
|
100
|
+
maxAge: 60 * 60 * 24, // 24 hours
|
|
101
|
+
authorize: undefined, // Magic link — no email check needed
|
|
102
|
+
async sendVerificationRequest({ identifier, url, expires }) {
|
|
103
|
+
const hours = Math.max(1, Math.floor((+expires - Date.now()) / (60 * 60 * 1000)));
|
|
104
|
+
const html = portalMagicLinkEmail(url, hours);
|
|
105
|
+
const siteUrl = process.env.CONVEX_SITE_URL;
|
|
106
|
+
if (!siteUrl) {
|
|
107
|
+
throw new Error("CONVEX_SITE_URL is required to send portal magic link email");
|
|
108
|
+
}
|
|
109
|
+
const response = await fetch(`${siteUrl}/auth-email-dispatch`, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: {
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
...(process.env.AUTH_EMAIL_DISPATCH_SECRET
|
|
114
|
+
? {
|
|
115
|
+
"x-auth-email-dispatch-secret": process.env.AUTH_EMAIL_DISPATCH_SECRET,
|
|
116
|
+
}
|
|
117
|
+
: {}),
|
|
118
|
+
},
|
|
119
|
+
body: JSON.stringify({
|
|
120
|
+
to: identifier,
|
|
121
|
+
subject: "Sign in to Convex Auth Portal",
|
|
122
|
+
html,
|
|
123
|
+
}),
|
|
124
|
+
});
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
throw new Error(`Could not send portal magic link email: ${response.status}`);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
}));
|
|
130
|
+
// Initialize the core AuthFactory()
|
|
131
|
+
const authResult = AuthFactory({
|
|
132
|
+
...config,
|
|
133
|
+
component,
|
|
134
|
+
providers,
|
|
135
|
+
});
|
|
136
|
+
this._auth = authResult.auth;
|
|
137
|
+
this.signIn = authResult.signIn;
|
|
138
|
+
this.signOut = authResult.signOut;
|
|
139
|
+
this.store = authResult.store;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Register HTTP routes for OAuth, JWT well-known endpoints, and portal
|
|
143
|
+
* static file serving.
|
|
144
|
+
*
|
|
145
|
+
* ```ts
|
|
146
|
+
* // convex/http.ts
|
|
147
|
+
* import { httpRouter } from "convex/server";
|
|
148
|
+
* import { auth } from "./auth";
|
|
149
|
+
*
|
|
150
|
+
* const http = httpRouter();
|
|
151
|
+
* auth.addHttpRoutes(http);
|
|
152
|
+
* export default http;
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
addHttpRoutes(http, opts) {
|
|
156
|
+
// Core auth routes (OAuth, JWKS, etc.)
|
|
157
|
+
this._auth.addHttpRoutes(http);
|
|
158
|
+
// Portal static file serving
|
|
159
|
+
const prefix = opts?.pathPrefix ?? "/auth";
|
|
160
|
+
// Create a shim that maps the self-hosting ComponentApi shape
|
|
161
|
+
// to the auth component's portalBridge functions
|
|
162
|
+
const selfHostingShim = {
|
|
163
|
+
lib: {
|
|
164
|
+
getByPath: this.component.portalBridge.getByPath,
|
|
165
|
+
getCurrentDeployment: this.component.portalBridge.getCurrentDeployment,
|
|
166
|
+
listAssets: this.component.portalBridge.listAssets,
|
|
167
|
+
recordAsset: this.component.portalBridge.recordAsset,
|
|
168
|
+
gcOldAssets: this.component.portalBridge.gcOldAssets,
|
|
169
|
+
setCurrentDeployment: this.component.portalBridge.setCurrentDeployment,
|
|
170
|
+
// generateUploadUrl is not needed — we use app storage directly
|
|
171
|
+
generateUploadUrl: undefined,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
registerStaticRoutes(http, selfHostingShim, {
|
|
175
|
+
pathPrefix: prefix,
|
|
176
|
+
spaFallback: opts?.spaFallback ?? true,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// ============================================================================
|
|
181
|
+
// Portal exports (standalone function)
|
|
182
|
+
// ============================================================================
|
|
183
|
+
/**
|
|
184
|
+
* Create portal function definitions from a ConvexAuth instance.
|
|
185
|
+
*
|
|
186
|
+
* This is a standalone function (not a class method) because Convex's
|
|
187
|
+
* bundler can trace through `export const { x } = fn(instance)` but
|
|
188
|
+
* cannot trace through `instance.method()`.
|
|
189
|
+
*
|
|
190
|
+
* ```ts
|
|
191
|
+
* export const { portalQuery, portalMutation, portalInternal } = Portal(auth);
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export function Portal(auth) {
|
|
195
|
+
const authComponent = auth.component;
|
|
196
|
+
const authHelper = auth._auth;
|
|
197
|
+
const portalUrl = auth.portalUrl;
|
|
198
|
+
const portalQuery = queryGeneric({
|
|
199
|
+
args: {
|
|
200
|
+
action: v.string(),
|
|
201
|
+
userId: v.optional(v.string()),
|
|
202
|
+
},
|
|
203
|
+
handler: async (ctx, { action, userId }) => {
|
|
204
|
+
const currentUserId = await authHelper.user.require(ctx);
|
|
205
|
+
// Allow isAdmin check without admin requirement
|
|
206
|
+
if (action === "isAdmin") {
|
|
207
|
+
try {
|
|
208
|
+
await requirePortalAdmin(ctx, authComponent, currentUserId);
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
await requirePortalAdmin(ctx, authComponent, currentUserId);
|
|
216
|
+
switch (action) {
|
|
217
|
+
case "listUsers":
|
|
218
|
+
return await ctx.runQuery(authComponent.public.userList);
|
|
219
|
+
case "listSessions":
|
|
220
|
+
return await ctx.runQuery(authComponent.public.sessionList);
|
|
221
|
+
case "getUser":
|
|
222
|
+
return await ctx.runQuery(authComponent.public.userGetById, {
|
|
223
|
+
userId: userId,
|
|
224
|
+
});
|
|
225
|
+
case "getUserSessions":
|
|
226
|
+
return await ctx.runQuery(authComponent.public.sessionListByUser, {
|
|
227
|
+
userId: userId,
|
|
228
|
+
});
|
|
229
|
+
case "getUserAccounts": {
|
|
230
|
+
const accounts = await ctx.runQuery(authComponent.public.accountListByUser, { userId: userId });
|
|
231
|
+
// Strip secrets — never send password hashes to the frontend
|
|
232
|
+
return accounts.map(({ secret: _, ...rest }) => rest);
|
|
233
|
+
}
|
|
234
|
+
// Invite validation (public within portal context)
|
|
235
|
+
case "validateInvite": {
|
|
236
|
+
// userId param repurposed as tokenHash for this action
|
|
237
|
+
const tokenHash = userId;
|
|
238
|
+
if (!tokenHash)
|
|
239
|
+
throw new Error("tokenHash required");
|
|
240
|
+
const invite = await ctx.runQuery(authComponent.public.inviteGetByTokenHash, { tokenHash });
|
|
241
|
+
if (!invite || invite.status !== "pending") {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
if (invite.expiresTime && invite.expiresTime < Date.now()) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
return { _id: invite._id, role: invite.role };
|
|
248
|
+
}
|
|
249
|
+
case "getCurrentDeployment":
|
|
250
|
+
return await ctx.runQuery(authComponent.portalBridge.getCurrentDeployment);
|
|
251
|
+
default:
|
|
252
|
+
throw new Error(`Unknown portal query action: ${action}`);
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
const portalMutation = mutationGeneric({
|
|
257
|
+
args: {
|
|
258
|
+
action: v.string(),
|
|
259
|
+
sessionId: v.optional(v.string()),
|
|
260
|
+
tokenHash: v.optional(v.string()),
|
|
261
|
+
},
|
|
262
|
+
handler: async (ctx, { action, sessionId, tokenHash, }) => {
|
|
263
|
+
const currentUserId = await authHelper.user.require(ctx);
|
|
264
|
+
switch (action) {
|
|
265
|
+
case "acceptInvite": {
|
|
266
|
+
if (!tokenHash)
|
|
267
|
+
throw new Error("tokenHash required");
|
|
268
|
+
const invite = await ctx.runQuery(authComponent.public.inviteGetByTokenHash, { tokenHash });
|
|
269
|
+
if (!invite)
|
|
270
|
+
throw new Error("Invalid invite token");
|
|
271
|
+
if (invite.status !== "pending") {
|
|
272
|
+
throw new Error(`Invite already ${invite.status}`);
|
|
273
|
+
}
|
|
274
|
+
if (invite.expiresTime && invite.expiresTime < Date.now()) {
|
|
275
|
+
throw new Error("Invite has expired");
|
|
276
|
+
}
|
|
277
|
+
await ctx.runMutation(authComponent.public.inviteAccept, {
|
|
278
|
+
inviteId: invite._id,
|
|
279
|
+
acceptedByUserId: currentUserId,
|
|
280
|
+
});
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
case "revokeSession": {
|
|
284
|
+
await requirePortalAdmin(ctx, authComponent, currentUserId);
|
|
285
|
+
await ctx.runMutation(authComponent.public.sessionDelete, {
|
|
286
|
+
sessionId: sessionId,
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
default:
|
|
291
|
+
throw new Error(`Unknown portal mutation action: ${action}`);
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
const portalInternal = internalMutationGeneric({
|
|
296
|
+
args: {
|
|
297
|
+
action: v.string(),
|
|
298
|
+
tokenHash: v.optional(v.string()),
|
|
299
|
+
path: v.optional(v.string()),
|
|
300
|
+
storageId: v.optional(v.string()),
|
|
301
|
+
blobId: v.optional(v.string()),
|
|
302
|
+
contentType: v.optional(v.string()),
|
|
303
|
+
deploymentId: v.optional(v.string()),
|
|
304
|
+
currentDeploymentId: v.optional(v.string()),
|
|
305
|
+
limit: v.optional(v.number()),
|
|
306
|
+
},
|
|
307
|
+
handler: async (ctx, args) => {
|
|
308
|
+
switch (args.action) {
|
|
309
|
+
// ---- Invite management (CLI) ----
|
|
310
|
+
case "createPortalInvite": {
|
|
311
|
+
await ctx.runMutation(authComponent.public.inviteCreate, {
|
|
312
|
+
tokenHash: args.tokenHash,
|
|
313
|
+
role: "portalAdmin",
|
|
314
|
+
status: "pending",
|
|
315
|
+
});
|
|
316
|
+
return { portalUrl };
|
|
317
|
+
}
|
|
318
|
+
// ---- Static hosting (CLI upload) ----
|
|
319
|
+
case "generateUploadUrl": {
|
|
320
|
+
return await ctx.storage.generateUploadUrl();
|
|
321
|
+
}
|
|
322
|
+
case "recordAsset": {
|
|
323
|
+
const { oldStorageId, oldBlobId } = await ctx.runMutation(authComponent.portalBridge.recordAsset, {
|
|
324
|
+
path: args.path,
|
|
325
|
+
...(args.storageId ? { storageId: args.storageId } : {}),
|
|
326
|
+
...(args.blobId ? { blobId: args.blobId } : {}),
|
|
327
|
+
contentType: args.contentType,
|
|
328
|
+
deploymentId: args.deploymentId,
|
|
329
|
+
});
|
|
330
|
+
if (oldStorageId) {
|
|
331
|
+
try {
|
|
332
|
+
await ctx.storage.delete(oldStorageId);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
// Ignore — old file may have been in different storage
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return oldBlobId ?? null;
|
|
339
|
+
}
|
|
340
|
+
case "gcOldAssets": {
|
|
341
|
+
const { storageIds, blobIds } = await ctx.runMutation(authComponent.portalBridge.gcOldAssets, { currentDeploymentId: args.currentDeploymentId });
|
|
342
|
+
for (const storageId of storageIds) {
|
|
343
|
+
try {
|
|
344
|
+
await ctx.storage.delete(storageId);
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// Ignore
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
await ctx.runMutation(authComponent.portalBridge.setCurrentDeployment, { deploymentId: args.currentDeploymentId });
|
|
351
|
+
return { deleted: storageIds.length, blobIds };
|
|
352
|
+
}
|
|
353
|
+
case "listAssets": {
|
|
354
|
+
return await ctx.runQuery(authComponent.portalBridge.listAssets, {
|
|
355
|
+
limit: args.limit,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
default:
|
|
359
|
+
throw new Error(`Unknown portalInternal action: ${args.action}`);
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
return { portalQuery, portalMutation, portalInternal };
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=convex-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convex-auth.js","sourceRoot":"","sources":["../../src/server/convex-auth.ts"],"names":[],"mappings":"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"}
|