mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-24 08:02:14 +03:00
Validated on a 3-PR combined board: kiro-connection-identity 8/8 (written failing-first — 3 new cases red on the pristine release/v3.8.50 tip, green with this change), typecheck:core + dashboard-typecheck clean, all static gates within baseline. Root cause is exactly right: a CodeWhisperer profile ARN identifies the profile, not the account, and distinct Builder ID accounts via social login can share one — the ARN is now trusted only alongside a non-contradicting account-level identifier (email/clientId). Closes #10815. Thank you @engenhariaandrereis01-ai!
This commit is contained in:
committed by
GitHub
parent
2904cf849d
commit
d137368fb5
1
changelog.d/fixes/10815-kiro-social-multi-account.md
Normal file
1
changelog.d/fixes/10815-kiro-social-multi-account.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(oauth): stop treating the Kiro profile ARN as an account identity in `findKiroConnectionByIdentity()`, so a second Google/GitHub social login creates a new connection instead of overwriting the first — distinct Builder ID accounts share the same CodeWhisperer profile ARN, and the social token is not a JWT, so no e-mail was available to disambiguate them (#10815)
|
||||
@@ -30,6 +30,27 @@ function providerData(connection: KiroConnectionLike): Record<string, unknown> {
|
||||
: {};
|
||||
}
|
||||
|
||||
/** True when the identity carries something that identifies the ACCOUNT (not the profile). */
|
||||
function hasAccountIdentifier(identity: KiroConnectionIdentity): boolean {
|
||||
return Boolean(folded(identity.email) || trimmed(identity.clientId));
|
||||
}
|
||||
|
||||
/** True when a shared field is present on both sides and disagrees — different accounts. */
|
||||
function contradictsAccount(
|
||||
connection: KiroConnectionLike,
|
||||
identity: KiroConnectionIdentity
|
||||
): boolean {
|
||||
const email = folded(identity.email);
|
||||
const existingEmail = folded(connection.email);
|
||||
if (email && existingEmail && email !== existingEmail) return true;
|
||||
|
||||
const clientId = trimmed(identity.clientId);
|
||||
const existingClientId = trimmed(providerData(connection).clientId);
|
||||
if (clientId && existingClientId && clientId !== existingClientId) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Find an existing Kiro account without comparing OAuth tokens or API keys. */
|
||||
export function findKiroConnectionByIdentity(
|
||||
connections: KiroConnectionLike[],
|
||||
@@ -45,7 +66,14 @@ export function findKiroConnectionByIdentity(
|
||||
const match = candidates.find(
|
||||
(connection) => trimmed(providerData(connection).profileArn) === profileArn
|
||||
);
|
||||
if (match) return match;
|
||||
// A profile ARN identifies the CodeWhisperer PROFILE, not the account: distinct
|
||||
// Builder ID accounts (Google/GitHub social login) share the same ARN. Accepting it
|
||||
// as identity made a second social login overwrite the first connection (#10815).
|
||||
// Only trust the ARN when the incoming identity carries an account-level identifier
|
||||
// that does not contradict the stored one.
|
||||
if (match && hasAccountIdentifier(identity) && !contradictsAccount(match, identity)) {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
const clientId = trimmed(identity.clientId);
|
||||
|
||||
@@ -79,3 +79,49 @@ test("findKiroConnectionByIdentity never overwrites a different authentication t
|
||||
null
|
||||
);
|
||||
});
|
||||
|
||||
// #10815 — a profile ARN identifies the CodeWhisperer profile, not the account: two
|
||||
// distinct social (Google/GitHub) Builder ID accounts share the same ARN, so matching
|
||||
// on it alone made the second login overwrite the first connection.
|
||||
const SHARED_PROFILE_ARN = "arn:aws:codewhisperer:us-east-1:1:profile/SHARED";
|
||||
|
||||
const firstSocialAccount = {
|
||||
id: "social-account-1",
|
||||
authType: "oauth",
|
||||
name: null,
|
||||
email: null,
|
||||
providerSpecificData: {
|
||||
profileArn: SHARED_PROFILE_ARN,
|
||||
authMethod: "imported",
|
||||
provider: "Github",
|
||||
},
|
||||
};
|
||||
|
||||
test("findKiroConnectionByIdentity does not match a shared profile ARN without an account identifier", () => {
|
||||
const match = findKiroConnectionByIdentity([firstSocialAccount], {
|
||||
authType: "oauth",
|
||||
profileArn: SHARED_PROFILE_ARN,
|
||||
email: null,
|
||||
});
|
||||
assert.equal(match, null);
|
||||
});
|
||||
|
||||
test("findKiroConnectionByIdentity treats diverging emails on a shared profile ARN as distinct accounts", () => {
|
||||
const stored = { ...firstSocialAccount, id: "social-a", email: "a@example.com" };
|
||||
const match = findKiroConnectionByIdentity([stored], {
|
||||
authType: "oauth",
|
||||
profileArn: SHARED_PROFILE_ARN,
|
||||
email: "b@example.com",
|
||||
});
|
||||
assert.equal(match, null);
|
||||
});
|
||||
|
||||
test("findKiroConnectionByIdentity still matches the same account on a shared profile ARN", () => {
|
||||
const stored = { ...firstSocialAccount, id: "social-a", email: "a@example.com" };
|
||||
const match = findKiroConnectionByIdentity([stored], {
|
||||
authType: "oauth",
|
||||
profileArn: SHARED_PROFILE_ARN,
|
||||
email: "a@example.com",
|
||||
});
|
||||
assert.equal(match?.id, "social-a");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user