Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion background.js
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ async function refreshHotmailAccessToken(account) {
formData.set('grant_type', 'refresh_token');
formData.set('refresh_token', account.refreshToken);
formData.set('scope', scopes.join(' '));
formData.set('redirect_uri', 'https://login.microsoftonline.com/common/oauth2/nativeclient');

let response;
try {
Expand Down Expand Up @@ -801,7 +802,11 @@ async function refreshHotmailAccessToken(account) {
}

if (!response.ok || !payload?.access_token) {
const errorText = payload?.error_description || payload?.error?.message || payload?.error || payload?.message || text || `HTTP ${response.status}`;
const rawErrorText = payload?.error_description || payload?.error?.message || payload?.error || payload?.message || text || `HTTP ${response.status}`;
const isCrossOriginError = typeof rawErrorText === 'string' && rawErrorText.includes('AADSTS90023');
const errorText = isCrossOriginError
? `Azure AD 拒绝了跨域令牌请求(AADSTS90023)。请在 Azure AD 应用注册中将应用平台改为"单页应用程序(SPA)",并将重定向 URI 设置为 https://login.microsoftonline.com/common/oauth2/nativeclient,或将应用类型改为"移动和桌面应用程序(Native)"。`
: rawErrorText;
const error = new Error(`Hotmail 令牌刷新失败:${errorText}`);
error.code = 'HOTMAIL_TOKEN_REFRESH_FAILED';
throw error;
Expand Down Expand Up @@ -1263,6 +1268,30 @@ async function closeLocalhostCallbackTabs(callbackUrl, options = {}) {
return matchedIds.length;
}

function buildLocalhostCleanupPrefix(rawUrl) {
if (!isLocalhostOAuthCallbackUrl(rawUrl)) return '';
const parsed = parseUrlSafely(rawUrl);
return parsed ? `${parsed.origin}/auth` : '';
}

async function closeTabsByUrlPrefix(prefix, options = {}) {
if (!prefix) return 0;

const { excludeTabIds = [] } = options;
const excluded = new Set(excludeTabIds.filter(id => Number.isInteger(id)));
const tabs = await chrome.tabs.query({});
const matchedIds = tabs
.filter((tab) => Number.isInteger(tab.id) && !excluded.has(tab.id))
.filter((tab) => typeof tab.url === 'string' && tab.url.startsWith(prefix))
.map((tab) => tab.id);

if (!matchedIds.length) return 0;

await chrome.tabs.remove(matchedIds).catch(() => { });
await addLog(`已关闭 ${matchedIds.length} 个匹配 ${prefix} 的 localhost 残留标签页。`, 'info');
return matchedIds.length;
}

async function pingContentScriptOnTab(tabId) {
if (!Number.isInteger(tabId)) return null;

Expand Down
6 changes: 6 additions & 0 deletions tests/step8-stop-cleanup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ async function addLog() {}
async function broadcastStopToContentScripts() {}
async function markRunningStepsStopped() {}
async function broadcastAutoRunStatus() {}
async function getState() {
return { autoRunning: false };
}
function isAutoRunScheduledState() {
return false;
}
function getStep8CallbackUrlFromNavigation() { return ''; }
function getStep8CallbackUrlFromTabUpdate() { return ''; }
async function completeStepFromBackground() {}
Expand Down
2 changes: 2 additions & 0 deletions tests/step9-localhost-cleanup-scope.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ const bundle = [
extractFunction('isLocalhostOAuthCallbackUrl'),
extractFunction('isLocalhostOAuthCallbackTabMatch'),
extractFunction('closeLocalhostCallbackTabs'),
extractFunction('buildLocalhostCleanupPrefix'),
extractFunction('closeTabsByUrlPrefix'),
extractFunction('handleStepData'),
].join('\n');

Expand Down