@robelest/convex-auth 0.0.2-preview.2 → 0.0.3-preview
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 +467 -64
- package/dist/client/index.d.ts +127 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +424 -1
- 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 +141 -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 -4
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/index.js +4 -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 +353 -9
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +328 -33
- package/dist/component/public.js.map +1 -1
- package/dist/component/schema.d.ts +168 -9
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +113 -7
- package/dist/component/schema.js.map +1 -1
- 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/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 +296 -0
- package/dist/server/convex-auth.d.ts.map +1 -0
- package/dist/server/convex-auth.js +480 -0
- package/dist/server/convex-auth.js.map +1 -0
- package/dist/server/email-templates.d.ts +18 -0
- package/dist/server/email-templates.d.ts.map +1 -0
- package/dist/server/email-templates.js +74 -0
- package/dist/server/email-templates.js.map +1 -0
- package/dist/server/implementation/apiKey.d.ts +74 -0
- package/dist/server/implementation/apiKey.d.ts.map +1 -0
- package/dist/server/implementation/apiKey.js +140 -0
- package/dist/server/implementation/apiKey.js.map +1 -0
- package/dist/server/implementation/index.d.ts +169 -7
- package/dist/server/implementation/index.d.ts.map +1 -1
- package/dist/server/implementation/index.js +220 -5
- 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/signIn.d.ts +13 -0
- package/dist/server/implementation/signIn.d.ts.map +1 -1
- package/dist/server/implementation/signIn.js +29 -15
- 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 +26 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +63 -16
- 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/provider_utils.d.ts +3 -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 +263 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/version.d.ts +2 -0
- package/dist/server/version.d.ts.map +1 -0
- package/dist/server/version.js +3 -0
- package/dist/server/version.js.map +1 -0
- package/package.json +7 -3
- package/src/cli/index.ts +49 -7
- package/src/cli/portal-link.ts +112 -0
- package/src/cli/portal-upload.ts +411 -0
- package/src/cli/utils.ts +248 -0
- package/src/client/index.ts +489 -1
- package/src/component/_generated/api.ts +72 -1
- package/src/component/_generated/component.ts +241 -4
- package/src/component/convex.config.ts +3 -0
- package/src/component/index.ts +8 -3
- package/src/component/portalBridge.ts +116 -0
- package/src/component/public.ts +373 -37
- package/src/component/schema.ts +122 -7
- package/src/providers/passkey.ts +35 -0
- package/src/providers/totp.ts +26 -0
- package/src/server/convex-auth.ts +602 -0
- package/src/server/email-templates.ts +77 -0
- package/src/server/implementation/apiKey.ts +185 -0
- package/src/server/implementation/index.ts +301 -8
- package/src/server/implementation/passkey.ts +650 -0
- package/src/server/implementation/redirects.ts +4 -11
- package/src/server/implementation/signIn.ts +41 -13
- package/src/server/implementation/totp.ts +366 -0
- package/src/server/index.ts +98 -34
- package/src/server/portal-email.ts +95 -0
- package/src/server/provider_utils.ts +42 -1
- package/src/server/types.ts +285 -4
- package/src/server/version.ts +2 -0
package/src/cli/utils.ts
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI utilities — logging, subprocess execution, file helpers.
|
|
3
|
+
*
|
|
4
|
+
* Eliminates duplication across index.ts, portal-upload.ts, portal-link.ts.
|
|
5
|
+
* All output goes to stderr so stdout can be piped cleanly.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import { execFileSync } from "child_process";
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
11
|
+
import { extname } from "path";
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Logging — unified output to stderr with chalk prefixes
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
const write = (msg: string) => process.stderr.write(msg + "\n");
|
|
18
|
+
|
|
19
|
+
export const log = {
|
|
20
|
+
step: (n: number, msg: string) => write(`${chalk.blue.bold(`[${n}]`)} ${chalk.bold(msg)}`),
|
|
21
|
+
success: (msg: string) => write(`${chalk.green("✔")} ${msg}`),
|
|
22
|
+
warn: (msg: string) => write(`${chalk.yellow.bold("!")} ${msg}`),
|
|
23
|
+
error: (msg: string, detail?: string) =>
|
|
24
|
+
write(`${chalk.red("✖")} ${msg}${detail ? `\n ${chalk.grey(`Error: ${detail}`)}` : ""}`),
|
|
25
|
+
info: (msg: string) => write(`${chalk.blue.bold("i")} ${msg}`),
|
|
26
|
+
blank: () => write(""),
|
|
27
|
+
raw: (msg: string) => write(msg),
|
|
28
|
+
indent: (msg: string) => write(` ${msg}`),
|
|
29
|
+
} as const;
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Subprocess — safe execFile with argument arrays (no shell injection)
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
export type DeploymentOptions = {
|
|
36
|
+
prod?: boolean;
|
|
37
|
+
adminKey?: string;
|
|
38
|
+
url?: string;
|
|
39
|
+
previewName?: string;
|
|
40
|
+
deploymentName?: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** Build CLI args array for Convex deployment selection. */
|
|
44
|
+
export const deploymentArgs = (opts: DeploymentOptions): string[] => {
|
|
45
|
+
const args: string[] = [];
|
|
46
|
+
if (opts.adminKey) args.push("--admin-key", opts.adminKey);
|
|
47
|
+
if (opts.url) args.push("--url", opts.url);
|
|
48
|
+
else if (opts.prod) args.push("--prod");
|
|
49
|
+
else if (opts.previewName) args.push("--preview-name", opts.previewName);
|
|
50
|
+
else if (opts.deploymentName) args.push("--deployment-name", opts.deploymentName);
|
|
51
|
+
return args;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** Run `npx convex env get <name>` and return the value. */
|
|
55
|
+
export const envGet = (name: string, opts: DeploymentOptions): string =>
|
|
56
|
+
execFileSync("npx", ["convex", "env", "get", ...deploymentArgs(opts), name], {
|
|
57
|
+
encoding: "utf-8",
|
|
58
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
59
|
+
}).slice(0, -1); // strip trailing newline
|
|
60
|
+
|
|
61
|
+
/** Run `npx convex env set <name> <value>`. */
|
|
62
|
+
export const envSet = (
|
|
63
|
+
name: string,
|
|
64
|
+
value: string,
|
|
65
|
+
opts: DeploymentOptions & { hideValue?: boolean },
|
|
66
|
+
): void => {
|
|
67
|
+
execFileSync(
|
|
68
|
+
"npx",
|
|
69
|
+
["convex", "env", "set", ...deploymentArgs(opts), "--", name, value],
|
|
70
|
+
{ stdio: opts.hideValue ? "ignore" : "inherit" },
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Run a Convex function via `npx convex run` and return parsed JSON output.
|
|
76
|
+
* Uses execFile with argument arrays — no shell injection.
|
|
77
|
+
*/
|
|
78
|
+
export const convexRun = <T = unknown>(
|
|
79
|
+
functionPath: string,
|
|
80
|
+
args: Record<string, unknown>,
|
|
81
|
+
opts: { prod?: boolean } = {},
|
|
82
|
+
): Promise<T> =>
|
|
83
|
+
new Promise((resolve, reject) => {
|
|
84
|
+
const { execFile } = require("child_process");
|
|
85
|
+
const cmdArgs = [
|
|
86
|
+
"convex", "run", functionPath,
|
|
87
|
+
JSON.stringify(args),
|
|
88
|
+
"--typecheck=disable",
|
|
89
|
+
"--codegen=disable",
|
|
90
|
+
...(opts.prod ? ["--prod"] : []),
|
|
91
|
+
];
|
|
92
|
+
execFile("npx", cmdArgs, { encoding: "utf-8" }, (error: any, stdout: string, stderr: string) => {
|
|
93
|
+
if (error) {
|
|
94
|
+
reject(new Error(`convex run ${functionPath} failed: ${stderr || stdout}`));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
resolve(JSON.parse(stdout.trim()) as T);
|
|
99
|
+
} catch {
|
|
100
|
+
// If output is not JSON, return raw string as-is
|
|
101
|
+
resolve(stdout.trim() as T);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// MIME types
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
|
|
110
|
+
const MIME_TYPES: Record<string, string> = {
|
|
111
|
+
".html": "text/html; charset=utf-8",
|
|
112
|
+
".js": "application/javascript; charset=utf-8",
|
|
113
|
+
".mjs": "application/javascript; charset=utf-8",
|
|
114
|
+
".css": "text/css; charset=utf-8",
|
|
115
|
+
".json": "application/json; charset=utf-8",
|
|
116
|
+
".png": "image/png",
|
|
117
|
+
".jpg": "image/jpeg",
|
|
118
|
+
".jpeg": "image/jpeg",
|
|
119
|
+
".gif": "image/gif",
|
|
120
|
+
".svg": "image/svg+xml",
|
|
121
|
+
".ico": "image/x-icon",
|
|
122
|
+
".webp": "image/webp",
|
|
123
|
+
".woff": "font/woff",
|
|
124
|
+
".woff2":"font/woff2",
|
|
125
|
+
".ttf": "font/ttf",
|
|
126
|
+
".txt": "text/plain; charset=utf-8",
|
|
127
|
+
".map": "application/json",
|
|
128
|
+
".webmanifest": "application/manifest+json",
|
|
129
|
+
".xml": "application/xml",
|
|
130
|
+
".br": "application/octet-stream",
|
|
131
|
+
".gz": "application/gzip",
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const getMimeType = (path: string): string =>
|
|
135
|
+
MIME_TYPES[extname(path).toLowerCase()] ?? "application/octet-stream";
|
|
136
|
+
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// File helpers
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Check for an existing non-empty source file (.ts or .js) at the given
|
|
143
|
+
* base path (without extension). Returns the path if found, null otherwise.
|
|
144
|
+
*/
|
|
145
|
+
export const findExistingSource = (basePath: string): string | null =>
|
|
146
|
+
[".ts", ".js"]
|
|
147
|
+
.map((ext) => basePath + ext)
|
|
148
|
+
.find((p) => existsSync(p) && readFileSync(p, "utf-8").trim() !== "")
|
|
149
|
+
?? null;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Test whether an existing file already matches a template.
|
|
153
|
+
* Templates use `$$` as wildcards and `;` followed by newline as flexible separators.
|
|
154
|
+
*/
|
|
155
|
+
export const matchesTemplate = (existing: string, template: string): boolean =>
|
|
156
|
+
new RegExp(
|
|
157
|
+
template
|
|
158
|
+
.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
159
|
+
.replace(/\\\$\\\$/g, ".*")
|
|
160
|
+
.replace(/;\n/g, ";.*"),
|
|
161
|
+
"s",
|
|
162
|
+
).test(existing);
|
|
163
|
+
|
|
164
|
+
/** Strip template markers from a source template. */
|
|
165
|
+
export const stripMarkers = (template: string): string =>
|
|
166
|
+
template.replace(/\$\$/g, "");
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Higher-order function: ensure a file matches a template.
|
|
170
|
+
*
|
|
171
|
+
* - If the file doesn't exist → create it
|
|
172
|
+
* - If it already matches → log success
|
|
173
|
+
* - If it exists but doesn't match → show instructions and prompt
|
|
174
|
+
*
|
|
175
|
+
* Returns a configured function bound to the convex folder path + TS preference.
|
|
176
|
+
*/
|
|
177
|
+
export const createFileEnsurer = (
|
|
178
|
+
convexFolderPath: string,
|
|
179
|
+
usesTypeScript: boolean,
|
|
180
|
+
promptFn: (message: string) => Promise<void>,
|
|
181
|
+
) => {
|
|
182
|
+
const path = require("path");
|
|
183
|
+
|
|
184
|
+
return async (
|
|
185
|
+
baseName: string,
|
|
186
|
+
template: string,
|
|
187
|
+
description: string,
|
|
188
|
+
): Promise<void> => {
|
|
189
|
+
const source = stripMarkers(template);
|
|
190
|
+
const filePath = path.join(convexFolderPath, baseName);
|
|
191
|
+
const existing = findExistingSource(filePath);
|
|
192
|
+
|
|
193
|
+
if (existing) {
|
|
194
|
+
const content = readFileSync(existing, "utf-8");
|
|
195
|
+
if (matchesTemplate(content, template)) {
|
|
196
|
+
log.success(`${chalk.bold(existing)} already configured.`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
log.info(`${chalk.bold(existing)} needs ${description}:`);
|
|
200
|
+
log.raw(`\n${indentBlock(source)}\n`);
|
|
201
|
+
await promptFn("Ready to continue?");
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const ext = usesTypeScript ? ".ts" : ".js";
|
|
206
|
+
const newPath = filePath + ext;
|
|
207
|
+
writeFileSync(newPath, source);
|
|
208
|
+
log.success(`Created ${chalk.bold(newPath)}`);
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/** Indent a multiline string (2 spaces, first line not indented). */
|
|
213
|
+
export const indentBlock = (s: string): string =>
|
|
214
|
+
s.replace(/^/gm, " ").slice(2);
|
|
215
|
+
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
// Crypto helpers (for portal invite links)
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
|
|
220
|
+
export { randomBytes, createHash } from "crypto";
|
|
221
|
+
|
|
222
|
+
/** Generate a URL-safe random token (32 bytes → 43 chars base64url). */
|
|
223
|
+
export const generateToken = (): string =>
|
|
224
|
+
require("crypto").randomBytes(32).toString("base64url");
|
|
225
|
+
|
|
226
|
+
/** SHA-256 hash a string and return the hex digest. */
|
|
227
|
+
export const hashToken = (token: string): string =>
|
|
228
|
+
require("crypto").createHash("sha256").update(token).digest("hex");
|
|
229
|
+
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
// Package version
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
|
|
234
|
+
/** Read the auth package version from its own package.json. */
|
|
235
|
+
export const getPackageVersion = (): string => {
|
|
236
|
+
try {
|
|
237
|
+
const pkgPath = require("path").resolve(__dirname, "..", "package.json");
|
|
238
|
+
return JSON.parse(readFileSync(pkgPath, "utf-8")).version;
|
|
239
|
+
} catch {
|
|
240
|
+
// Fallback: if running from dist/bin.cjs, package.json is two levels up
|
|
241
|
+
try {
|
|
242
|
+
const pkgPath = require("path").resolve(__dirname, "..", "..", "package.json");
|
|
243
|
+
return JSON.parse(readFileSync(pkgPath, "utf-8")).version;
|
|
244
|
+
} catch {
|
|
245
|
+
return "unknown";
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|