fix(mount): reuse stored password when editing
Empty password on update keeps secret; test connection with mountId reuses decrypted secret.
This commit is contained in:
parent
fb3747a66c
commit
a1483299f3
|
|
@ -183,6 +183,8 @@ function MountsInner(props: { locale: Locale }) {
|
||||||
username: form.username.trim() || undefined,
|
username: form.username.trim() || undefined,
|
||||||
password: form.password || undefined,
|
password: form.password || undefined,
|
||||||
rootPath: form.rootPath.trim() || "/",
|
rootPath: form.rootPath.trim() || "/",
|
||||||
|
// 编辑留空密码时由服务端复用已存密文
|
||||||
|
mountId: mode === "edit" ? (editId ?? undefined) : undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export const mediaRouter = t.router({
|
||||||
.mutation(({ ctx, input }) => mountService.delete(ctx.userId, input.id)),
|
.mutation(({ ctx, input }) => mountService.delete(ctx.userId, input.id)),
|
||||||
mountTest: protectedProcedure
|
mountTest: protectedProcedure
|
||||||
.input(mountSchemas.test)
|
.input(mountSchemas.test)
|
||||||
.mutation(({ input }) => mountService.test(input)),
|
.mutation(({ ctx, input }) => mountService.test(input, ctx.userId)),
|
||||||
mountListDir: protectedProcedure
|
mountListDir: protectedProcedure
|
||||||
.input(mountSchemas.listDir)
|
.input(mountSchemas.listDir)
|
||||||
.query(({ ctx, input }) => mountService.listDir(ctx.userId, input)),
|
.query(({ ctx, input }) => mountService.listDir(ctx.userId, input)),
|
||||||
|
|
|
||||||
|
|
@ -116,8 +116,9 @@ export const mountService = {
|
||||||
patch["baseUrl"] = input.baseUrl;
|
patch["baseUrl"] = input.baseUrl;
|
||||||
}
|
}
|
||||||
if (input.username !== undefined) patch["username"] = input.username;
|
if (input.username !== undefined) patch["username"] = input.username;
|
||||||
if (input.password !== undefined) {
|
// 密码留空/未传 = 保持原密文,避免编辑时重复输入
|
||||||
patch["secretEnc"] = input.password ? encryptSecret(input.password) : "";
|
if (input.password) {
|
||||||
|
patch["secretEnc"] = encryptSecret(input.password);
|
||||||
}
|
}
|
||||||
if (input.rootPath !== undefined) patch["rootPath"] = input.rootPath;
|
if (input.rootPath !== undefined) patch["rootPath"] = input.rootPath;
|
||||||
if (input.enabled !== undefined) patch["enabled"] = input.enabled;
|
if (input.enabled !== undefined) patch["enabled"] = input.enabled;
|
||||||
|
|
@ -135,22 +136,32 @@ export const mountService = {
|
||||||
return { success: true, removedItems: removedIds.length };
|
return { success: true, removedItems: removedIds.length };
|
||||||
},
|
},
|
||||||
|
|
||||||
async test(input: {
|
async test(
|
||||||
|
input: {
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
username?: string | undefined;
|
username?: string | undefined;
|
||||||
password?: string | undefined;
|
password?: string | undefined;
|
||||||
rootPath: string;
|
rootPath: string;
|
||||||
}): Promise<{ ok: boolean; message: string }> {
|
mountId?: string | undefined;
|
||||||
|
},
|
||||||
|
userId?: string,
|
||||||
|
): Promise<{ ok: boolean; message: string }> {
|
||||||
try {
|
try {
|
||||||
assertSafeWebdavUrl(input.baseUrl);
|
assertSafeWebdavUrl(input.baseUrl);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { ok: false, message: e instanceof Error ? e.message : "地址不合法" };
|
return { ok: false, message: e instanceof Error ? e.message : "地址不合法" };
|
||||||
}
|
}
|
||||||
|
// 编辑时密码留空:复用已存密文测连,避免每次重填
|
||||||
|
let password = input.password;
|
||||||
|
if (!password && input.mountId && userId) {
|
||||||
|
const existing = await mountDao.getByIdForUser(input.mountId, userId);
|
||||||
|
if (existing?.secretEnc) password = decryptSecret(existing.secretEnc);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const client = createWebdav({
|
const client = createWebdav({
|
||||||
baseUrl: input.baseUrl,
|
baseUrl: input.baseUrl,
|
||||||
username: input.username,
|
username: input.username,
|
||||||
password: input.password,
|
password,
|
||||||
});
|
});
|
||||||
// 1) 先探 WebDAV 根:区分「认证/不是 WebDAV」与「根路径写错」
|
// 1) 先探 WebDAV 根:区分「认证/不是 WebDAV」与「根路径写错」
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ export const mountSchemas = {
|
||||||
username: z.string().max(200).optional(),
|
username: z.string().max(200).optional(),
|
||||||
password: z.string().max(500).optional(),
|
password: z.string().max(500).optional(),
|
||||||
rootPath: z.string().max(1000).default("/"),
|
rootPath: z.string().max(1000).default("/"),
|
||||||
|
/** 编辑已有挂载时传入:密码留空则复用库内密文 */
|
||||||
|
mountId: z.string().optional(),
|
||||||
}),
|
}),
|
||||||
listDir: z.object({
|
listDir: z.object({
|
||||||
mountId: id,
|
mountId: id,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue