-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathexplore-outlook-snippets.ts
More file actions
153 lines (127 loc) · 4.93 KB
/
explore-outlook-snippets.ts
File metadata and controls
153 lines (127 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import { connectToSuperhuman, disconnect } from "./src/superhuman-api";
async function main() {
const conn = await connectToSuperhuman(9333);
if (!conn) { console.log("No connection"); process.exit(1); }
// Check if there are multiple accounts and how snippets work across them
const result = await conn.Runtime.evaluate({
expression: `
(() => {
const findings = {};
// Check for MicrosoftAccount or OutlookAccount
if (window.MicrosoftAccount) {
findings.hasMicrosoftAccount = true;
findings.microsoftAccountKeys = Object.keys(window.MicrosoftAccount).slice(0, 30);
// Check for settings on Microsoft account
if (window.MicrosoftAccount.settings) {
findings.microsoftSettings = {
hasSettings: true,
cacheKeys: window.MicrosoftAccount.settings._cache ?
Object.keys(window.MicrosoftAccount.settings._cache) : null
};
}
}
// Check ViewState for multiple accounts
const vs = window.ViewState;
if (vs) {
// Look for account-related properties
const accountProps = Object.keys(vs).filter(k =>
k.toLowerCase().includes('account')
);
findings.viewStateAccountProps = accountProps;
// Check for accounts array
if (vs._accounts || vs.accounts) {
const accounts = vs._accounts || vs.accounts;
findings.accountsCount = Array.isArray(accounts) ? accounts.length : 'not array';
}
}
// Check GoogleAccount structure
const ga = window.GoogleAccount;
if (ga) {
findings.googleAccountType = ga.constructor?.name;
// Check if snippets are stored at account level or shared
const settings = ga.settings;
if (settings) {
findings.googleSettingsAccount = settings.account?.constructor?.name;
// Check if there's a shared settings store
if (settings._sharedCache) {
findings.hasSharedCache = true;
}
}
}
// Look for a global Accounts or AccountManager
const globalKeys = Object.keys(window).filter(k =>
k.toLowerCase().includes('account') &&
typeof window[k] === 'object' &&
window[k] !== null
);
findings.globalAccountKeys = globalKeys;
// Check for AccountSwitcher or similar
if (window.AccountSwitcher) {
findings.hasAccountSwitcher = true;
}
return findings;
})()
`,
returnByValue: true,
});
console.log("=== Account Structure ===\n");
console.log(JSON.stringify(result.result.value, null, 2));
// Check if snippets are actually per-account or global
const snippetScopeResult = await conn.Runtime.evaluate({
expression: `
(() => {
const ga = window.GoogleAccount;
if (!ga?.settings) return { error: "no settings" };
// Check the settings.set method to understand where data goes
const setMethod = ga.settings.set?.toString?.();
// Check if there's an accountId in the settings path
const accountId = ga.settings.account?._accountId ||
ga.settings.account?.emailAddress ||
ga._accountId;
// Check the _cache structure
const cacheStructure = {
hasSnippets: 'snippets' in (ga.settings._cache || {}),
topLevelKeys: Object.keys(ga.settings._cache || {}).slice(0, 20)
};
return {
accountId,
cacheStructure,
setMethodPreview: setMethod?.slice(0, 300)
};
})()
`,
returnByValue: true,
});
console.log("\n=== Snippet Scope Analysis ===\n");
console.log(JSON.stringify(snippetScopeResult.result.value, null, 2));
// Check for base Account class that both Google and Microsoft might inherit from
const baseAccountResult = await conn.Runtime.evaluate({
expression: `
(() => {
const ga = window.GoogleAccount;
if (!ga) return { error: "no GoogleAccount" };
// Get prototype chain
const protoChain = [];
let proto = Object.getPrototypeOf(ga);
while (proto && proto !== Object.prototype) {
protoChain.push(proto.constructor?.name || 'anonymous');
proto = Object.getPrototypeOf(proto);
}
// Check if settings has a common interface
const settingsProto = ga.settings ?
Object.getPrototypeOf(ga.settings)?.constructor?.name : null;
return {
protoChain,
settingsProto,
hasPortal: !!ga.portal,
portalMethods: ga.portal ? Object.keys(ga.portal).slice(0, 20) : null
};
})()
`,
returnByValue: true,
});
console.log("\n=== Base Account Analysis ===\n");
console.log(JSON.stringify(baseAccountResult.result.value, null, 2));
await disconnect(conn);
}
main().catch(console.error);