feat: 彩虹登录支持选择多种登录方式

This commit is contained in:
xiaojunnuo
2026-05-14 01:39:22 +08:00
parent 45dedf5bc7
commit 7aa0c7e491
16 changed files with 371 additions and 88 deletions
@@ -1,12 +1,14 @@
import assert from "assert";
import esmock from "esmock";
import { AutoFix, buildEabAccountKeyValue, buildLegacyGoogleAccountConfigWhere, parseStorageValue } from "./auto-fix.js";
import { AutoFix, buildEabAccountKeyValue, buildLegacyGoogleAccountConfigWhere, buildOauthBoundType, parseStorageValue } from "./auto-fix.js";
function createAutoFix(options: { pluginConfigService?: any; accessService?: any; storageService?: any }) {
function createAutoFix(options: { pluginConfigService?: any; accessService?: any; storageService?: any; sysSettingsService?: any; oauthBoundService?: any }) {
const autoFix = new AutoFix();
autoFix.pluginConfigService = options.pluginConfigService;
autoFix.accessService = options.accessService;
autoFix.storageService = options.storageService;
autoFix.sysSettingsService = options.sysSettingsService;
autoFix.oauthBoundService = options.oauthBoundService;
return autoFix;
}
@@ -42,6 +44,11 @@ describe("AutoFix", () => {
});
});
it("builds OAuth subtype bound type", () => {
assert.equal(buildOauthBoundType("clogin", "alipay"), "clogin:alipay");
assert.equal(buildOauthBoundType("github"), "github");
});
it("finds legacy Google account config by exact email key only", async () => {
let findOneWhere: any;
let findCalled = false;
@@ -107,6 +114,25 @@ describe("AutoFix", () => {
} as any,
accessService: null as any,
storageService: null as any,
sysSettingsService: {
async getPublicSettings() {
return {
oauthProviders: {},
};
},
},
oauthBoundService: {
async transaction(callback: any) {
return await callback({
async findOne() {
return null;
},
async update() {
return { affected: 0 };
},
});
},
},
});
await autoFix.init();
@@ -179,4 +205,97 @@ describe("AutoFix", () => {
});
});
it("fixes legacy OAuth bound type from string addon loginType and converts loginType to array", async () => {
const updates: any[] = [];
const autoFix = createAutoFix({
pluginConfigService: null as any,
accessService: null as any,
storageService: null as any,
sysSettingsService: {
async getPublicSettings() {
return {
oauthProviders: {
clogin: {
addonId: 1,
},
},
};
},
},
oauthBoundService: {
async transaction(callback: any) {
return await callback({
async findOne(entity: any, options: any) {
assert.equal(entity.name, "AddonEntity");
assert.deepEqual(options, { where: { id: 1 } });
return {
id: 1,
setting: JSON.stringify({
loginType: "alipay",
}),
};
},
async update(entity: any, where: any, value: any) {
updates.push({ entity: entity.name, where, value });
return { affected: entity.name === "OauthBoundEntity" ? 1 : 0 };
},
});
},
},
});
await autoFix.fixOauthSubtypeBoundType();
assert.deepEqual(updates[0], {
entity: "OauthBoundEntity",
where: { type: "clogin" },
value: { type: "clogin:alipay" },
});
assert.equal(updates[1].entity, "AddonEntity");
assert.deepEqual(updates[1].where, { id: 1 });
assert.deepEqual(JSON.parse(updates[1].value.setting).loginType, ["alipay"]);
});
it("skips OAuth subtype fix when addon loginType is already not legacy string", async () => {
let updateCalled = false;
const autoFix = createAutoFix({
pluginConfigService: null as any,
accessService: null as any,
storageService: null as any,
sysSettingsService: {
async getPublicSettings() {
return {
oauthProviders: {
clogin: {
addonId: 1,
},
},
};
},
},
oauthBoundService: {
async transaction(callback: any) {
return await callback({
async findOne() {
return {
id: 1,
setting: JSON.stringify({
loginType: ["alipay", "github"],
}),
};
},
async update() {
updateCalled = true;
return { affected: 0 };
},
});
},
},
});
await autoFix.fixOauthSubtypeBoundType();
assert.equal(updateCalled, false);
});
});