fix kiro verification active page adoption
This commit is contained in:
@@ -444,6 +444,52 @@
|
|||||||
return Boolean(await chrome.tabs.get(tabId).catch(() => null));
|
return Boolean(await chrome.tabs.get(tabId).catch(() => null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isKiroRegisterCandidateUrl(rawUrl = '') {
|
||||||
|
let parsed = null;
|
||||||
|
try {
|
||||||
|
parsed = new URL(String(rawUrl || '').trim());
|
||||||
|
} catch (_error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const hostname = parsed.hostname.toLowerCase();
|
||||||
|
return hostname === 'app.kiro.dev'
|
||||||
|
|| hostname === 'kiro.dev'
|
||||||
|
|| hostname === 'view.awsapps.com'
|
||||||
|
|| hostname === 'login.awsapps.com'
|
||||||
|
|| hostname === 'profile.aws.amazon.com'
|
||||||
|
|| hostname === 'profile.aws'
|
||||||
|
|| hostname.endsWith('.profile.aws.amazon.com')
|
||||||
|
|| hostname.endsWith('.profile.aws')
|
||||||
|
|| hostname === 'signin.aws.amazon.com'
|
||||||
|
|| hostname === 'signin.aws'
|
||||||
|
|| hostname.endsWith('.signin.aws.amazon.com')
|
||||||
|
|| hostname.endsWith('.signin.aws');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getActiveKiroRegisterTabId() {
|
||||||
|
if (!chrome?.tabs?.query) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const queryAttempts = [
|
||||||
|
{ active: true, lastFocusedWindow: true },
|
||||||
|
{ active: true, currentWindow: true },
|
||||||
|
{ active: true },
|
||||||
|
];
|
||||||
|
for (const queryInfo of queryAttempts) {
|
||||||
|
const tabs = await chrome.tabs.query(queryInfo).catch(() => []);
|
||||||
|
const matchedTab = (Array.isArray(tabs) ? tabs : []).find((tab) => (
|
||||||
|
Number.isInteger(tab?.id) && isKiroRegisterCandidateUrl(tab?.url)
|
||||||
|
));
|
||||||
|
if (Number.isInteger(matchedTab?.id)) {
|
||||||
|
return matchedTab.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
async function getExecutionState(state = {}) {
|
async function getExecutionState(state = {}) {
|
||||||
if (state && typeof state === 'object' && !Array.isArray(state) && Object.keys(state).length) {
|
if (state && typeof state === 'object' && !Array.isArray(state) && Object.keys(state).length) {
|
||||||
return state;
|
return state;
|
||||||
@@ -521,6 +567,17 @@
|
|||||||
return tabId;
|
return tabId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const activeKiroTabId = await getActiveKiroRegisterTabId();
|
||||||
|
if (Number.isInteger(activeKiroTabId)) {
|
||||||
|
await registerTab(KIRO_REGISTER_PAGE_SOURCE_ID, activeKiroTabId);
|
||||||
|
await setState(mergeRuntimePatch(state, {
|
||||||
|
session: {
|
||||||
|
registerTabId: activeKiroTabId,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
return activeKiroTabId;
|
||||||
|
}
|
||||||
|
|
||||||
if (!loginUrl) {
|
if (!loginUrl) {
|
||||||
throw new Error(options.missingUrlMessage || '缺少 Kiro 注册页地址,请先执行步骤 1。');
|
throw new Error(options.missingUrlMessage || '缺少 Kiro 注册页地址,请先执行步骤 1。');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,6 +276,94 @@ test('kiro verification polling uses the registration email field instead of pag
|
|||||||
assert.equal(getKiroRuntime(completedPayload).register?.email, 'skater-twine-carve@duck.com');
|
assert.equal(getKiroRuntime(completedPayload).register?.email, 'skater-twine-carve@duck.com');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('kiro verification step can adopt the active AWS verify-otp page without step 1 runtime', async () => {
|
||||||
|
const api = loadRegisterRunnerApi();
|
||||||
|
const currentState = {
|
||||||
|
email: 'tmp3x58ft2ivc@edu.email.qlhazycoder.tech',
|
||||||
|
registrationEmailState: {
|
||||||
|
current: 'tmp3x58ft2ivc@edu.email.qlhazycoder.tech',
|
||||||
|
previous: 'tmp3x58ft2ivc@edu.email.qlhazycoder.tech',
|
||||||
|
source: 'manual',
|
||||||
|
updatedAt: Date.now(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const sentMessages = [];
|
||||||
|
const statePatches = [];
|
||||||
|
const registeredTabs = [];
|
||||||
|
const pollPayloads = [];
|
||||||
|
let completedPayload = null;
|
||||||
|
const runner = api.createKiroRegisterRunner({
|
||||||
|
addLog: async () => {},
|
||||||
|
chrome: {
|
||||||
|
tabs: {
|
||||||
|
query: async () => [{
|
||||||
|
id: 301,
|
||||||
|
active: true,
|
||||||
|
url: 'https://profile.aws.amazon.com/?workflowID=b4e8f9ff-3d60-40ce-90ec-d2113d951b08#/signup/verify-otp',
|
||||||
|
}],
|
||||||
|
update: async () => {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
completeNodeFromBackground: async (_nodeId, payload) => {
|
||||||
|
completedPayload = payload;
|
||||||
|
},
|
||||||
|
getMailConfig: () => ({
|
||||||
|
provider: 'cloudflare-temp-email',
|
||||||
|
source: 'cloudflare-temp-email',
|
||||||
|
label: 'Cloudflare Temp Email',
|
||||||
|
}),
|
||||||
|
getState: async () => currentState,
|
||||||
|
getTabId: async () => null,
|
||||||
|
isTabAlive: async () => false,
|
||||||
|
pollCloudflareTempEmailVerificationCode: async (_step, _state, payload) => {
|
||||||
|
pollPayloads.push(payload);
|
||||||
|
return { code: '248680', emailTimestamp: 2000, mailId: 'mail-active' };
|
||||||
|
},
|
||||||
|
registerTab: async (source, tabId) => {
|
||||||
|
registeredTabs.push({ source, tabId });
|
||||||
|
},
|
||||||
|
sendToContentScriptResilient: async (_sourceId, message) => {
|
||||||
|
sentMessages.push(message);
|
||||||
|
if (message.type === 'ENSURE_KIRO_PAGE_STATE') {
|
||||||
|
return {
|
||||||
|
state: 'register_otp_page',
|
||||||
|
url: 'https://profile.aws.amazon.com/?workflowID=b4e8f9ff-3d60-40ce-90ec-d2113d951b08#/signup/verify-otp',
|
||||||
|
email: 'tmp3x58ft2ivc@edu.email.qlhazycoder.tech',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (message.type === 'EXECUTE_NODE') {
|
||||||
|
return { submitted: true, state: 'verification_submitted' };
|
||||||
|
}
|
||||||
|
if (message.type === 'ENSURE_KIRO_STATE_CHANGE') {
|
||||||
|
return {
|
||||||
|
state: 'create_password_page',
|
||||||
|
url: 'https://profile.aws.amazon.com/?workflowID=b4e8f9ff-3d60-40ce-90ec-d2113d951b08#/signup/create-password',
|
||||||
|
email: 'tmp3x58ft2ivc@edu.email.qlhazycoder.tech',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
setState: async (patch) => {
|
||||||
|
statePatches.push(patch);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await runner.executeKiroSubmitVerificationCode({
|
||||||
|
nodeId: 'kiro-submit-verification-code',
|
||||||
|
...currentState,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.deepEqual(registeredTabs, [{ source: 'kiro-register-page', tabId: 301 }]);
|
||||||
|
assert.equal(getKiroRuntime(statePatches[0]).session?.registerTabId, 301);
|
||||||
|
assert.equal(pollPayloads[0].targetEmail, 'tmp3x58ft2ivc@edu.email.qlhazycoder.tech');
|
||||||
|
assert.equal(sentMessages.some((message) => (
|
||||||
|
message.type === 'EXECUTE_NODE'
|
||||||
|
&& message.nodeId === 'kiro-submit-verification-code'
|
||||||
|
&& message.payload?.code === '248680'
|
||||||
|
)), true);
|
||||||
|
assert.equal(getKiroRuntime(completedPayload).register?.email, 'tmp3x58ft2ivc@edu.email.qlhazycoder.tech');
|
||||||
|
});
|
||||||
|
|
||||||
test('kiro submit-email reuses the step 1 register tab even when the source registry was reset', async () => {
|
test('kiro submit-email reuses the step 1 register tab even when the source registry was reset', async () => {
|
||||||
const api = loadRegisterRunnerApi();
|
const api = loadRegisterRunnerApi();
|
||||||
const currentState = {
|
const currentState = {
|
||||||
|
|||||||
Reference in New Issue
Block a user