
























@@ -14,6 +14,7 @@ import {
1414import {
1515clearRuntimeAuthProfileStoreSnapshots,
1616ensureAuthProfileStore,
17+ensureAuthProfileStoreWithoutExternalProfiles,
1718saveAuthProfileStore,
1819} from "./store.js";
1920import type { AuthProfileStore, OAuthCredential } from "./types.js";
@@ -145,6 +146,94 @@ describe("OAuthManagerRefreshError", () => {
145146});
146147147148describe("createOAuthManager", () => {
149+it("does not overlay external auth while checking main-store adoption", async () => {
150+const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "oauth-manager-main-adopt-"));
151+tempDirs.push(tempRoot);
152+process.env.OPENCLAW_STATE_DIR = tempRoot;
153+const mainAgentDir = path.join(tempRoot, "agents", "main", "agent");
154+const agentDir = path.join(tempRoot, "agents", "sub", "agent");
155+process.env.OPENCLAW_AGENT_DIR = mainAgentDir;
156+process.env.PI_CODING_AGENT_DIR = mainAgentDir;
157+await fs.mkdir(agentDir, { recursive: true });
158+await fs.mkdir(mainAgentDir, { recursive: true });
159+160+const profileId = "openai-codex:default";
161+const subCredential = createCredential({
162+access: "expired-sub-access",
163+refresh: "sub-refresh",
164+expires: Date.now() - 60_000,
165+});
166+const mainCredential = createCredential({
167+access: "expired-main-access",
168+refresh: "main-refresh",
169+expires: Date.now() - 30_000,
170+});
171+saveAuthProfileStore(
172+{
173+version: 1,
174+profiles: {
175+[profileId]: subCredential,
176+},
177+},
178+agentDir,
179+{ filterExternalAuthProfiles: false },
180+);
181+saveAuthProfileStore(
182+{
183+version: 1,
184+profiles: {
185+[profileId]: mainCredential,
186+},
187+},
188+mainAgentDir,
189+{ filterExternalAuthProfiles: false },
190+);
191+externalAuthTesting.setResolveExternalAuthProfilesForTest(() => [
192+{
193+ profileId,
194+credential: createCredential({
195+access: "external-fresh-access",
196+refresh: "external-fresh-refresh",
197+expires: Date.now() + 60_000,
198+}),
199+persistence: "runtime-only",
200+},
201+]);
202+203+const refreshCredential = vi.fn(async (credential: OAuthCredential) => {
204+expect(credential.access).toBe("expired-main-access");
205+return {
206+access: "rotated-main-access",
207+refresh: "rotated-main-refresh",
208+expires: Date.now() + 60_000,
209+};
210+});
211+const manager = createOAuthManager({
212+buildApiKey: async (_provider, credential) => credential.access,
213+ refreshCredential,
214+readBootstrapCredential: () => null,
215+isRefreshTokenReusedError: () => false,
216+});
217+218+const result = await manager.resolveOAuthAccess({
219+store: ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
220+allowKeychainPrompt: false,
221+}),
222+ profileId,
223+credential: subCredential,
224+ agentDir,
225+});
226+227+expect(refreshCredential).toHaveBeenCalledTimes(1);
228+expect(result).toEqual({
229+apiKey: "rotated-main-access",
230+credential: expect.objectContaining({
231+access: "rotated-main-access",
232+refresh: "rotated-main-refresh",
233+}),
234+});
235+});
236+148237it("refreshes with the adopted external oauth credential", async () => {
149238const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "oauth-manager-refresh-"));
150239tempDirs.push(tempRoot);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。