Files
mnote/convex/users.ts
T

78 lines
2.1 KiB
TypeScript

import { query } from "./_generated/server";
import { mutation } from "./_generated/server";
import { v } from "convex/values";
import { getAuthUserId } from "@convex-dev/auth/server";
function normalizeAccount(value: string) {
return value.trim().toLowerCase();
}
export const resolveLoginAccount = query({
args: {
account: v.string(),
},
handler: async (ctx, args) => {
const account = normalizeAccount(args.account);
if (!account) {
return null;
}
const users = await ctx.db.query("users").collect();
const user = users.find((row: any) => {
const email = normalizeAccount(String(row.email ?? ""));
const name = normalizeAccount(String(row.name ?? ""));
return email === account || name === account;
});
if (!user) {
return null;
}
return {
userId: user._id,
email: String((user as any).email ?? ""),
name: String((user as any).name ?? ""),
};
},
});
function normalizeUsername(raw: string): string {
const username = String(raw ?? "").trim();
if (!username) throw new Error("用户名不能为空");
if (username.length < 2 || username.length > 32) throw new Error("用户名长度需为 2-32 个字符");
if (/\s/.test(username)) throw new Error("用户名不能包含空格");
return username;
}
export const currentUser = query({
args: {},
handler: async (ctx) => {
const userId = await getAuthUserId(ctx);
if (userId === null) {
return null;
}
return await ctx.db.get(userId);
},
});
export const setMyUsername = mutation({
args: { username: v.string() },
handler: async (ctx, args) => {
const userId = await getAuthUserId(ctx);
if (userId === null) throw new Error("未登录");
const username = normalizeUsername(args.username);
const existing = await ctx.db
.query("users")
.filter((q) => q.eq(q.field("name"), username))
.first();
if (existing && String(existing._id) !== String(userId)) {
throw new Error("用户名已被占用");
}
await ctx.db.patch(userId, { name: username });
return { ok: true, username };
},
});