latchkey 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +4 -4
- package/dist/integrations/SKILL.md +71 -0
- package/dist/package.json +67 -0
- package/dist/scripts/encryptFile.d.ts +21 -0
- package/dist/scripts/encryptFile.d.ts.map +1 -0
- package/dist/scripts/encryptFile.js +101 -0
- package/dist/scripts/encryptFile.js.map +1 -0
- package/dist/src/apiCredentials.d.ts +83 -1
- package/dist/src/apiCredentials.d.ts.map +1 -1
- package/dist/src/apiCredentials.js +83 -1
- package/dist/src/apiCredentials.js.map +1 -1
- package/dist/src/browserState.d.ts +8 -0
- package/dist/src/browserState.d.ts.map +1 -0
- package/dist/src/browserState.js +21 -0
- package/dist/src/browserState.js.map +1 -0
- package/dist/src/cli.js +2 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/cliCommands.d.ts.map +1 -1
- package/dist/src/cliCommands.js +122 -17
- package/dist/src/cliCommands.js.map +1 -1
- package/dist/src/oauthUtils.d.ts +49 -0
- package/dist/src/oauthUtils.d.ts.map +1 -0
- package/dist/src/oauthUtils.js +183 -0
- package/dist/src/oauthUtils.js.map +1 -0
- package/dist/src/playwrightUtils.d.ts +8 -1
- package/dist/src/playwrightUtils.d.ts.map +1 -1
- package/dist/src/playwrightUtils.js +25 -8
- package/dist/src/playwrightUtils.js.map +1 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +2 -2
- package/dist/src/registry.js.map +1 -1
- package/dist/src/services/base.d.ts +31 -5
- package/dist/src/services/base.d.ts.map +1 -1
- package/dist/src/services/base.js +12 -8
- package/dist/src/services/base.js.map +1 -1
- package/dist/src/services/discord.d.ts +2 -0
- package/dist/src/services/discord.d.ts.map +1 -1
- package/dist/src/services/discord.js +3 -0
- package/dist/src/services/discord.js.map +1 -1
- package/dist/src/services/dropbox.d.ts +3 -1
- package/dist/src/services/dropbox.d.ts.map +1 -1
- package/dist/src/services/dropbox.js +7 -5
- package/dist/src/services/dropbox.js.map +1 -1
- package/dist/src/services/github.d.ts +3 -1
- package/dist/src/services/github.d.ts.map +1 -1
- package/dist/src/services/github.js +18 -8
- package/dist/src/services/github.js.map +1 -1
- package/dist/src/services/google.d.ts +35 -0
- package/dist/src/services/google.d.ts.map +1 -0
- package/dist/src/services/google.js +358 -0
- package/dist/src/services/google.js.map +1 -0
- package/dist/src/services/index.d.ts +2 -0
- package/dist/src/services/index.d.ts.map +1 -1
- package/dist/src/services/index.js +2 -0
- package/dist/src/services/index.js.map +1 -1
- package/dist/src/services/linear.d.ts +3 -1
- package/dist/src/services/linear.d.ts.map +1 -1
- package/dist/src/services/linear.js +7 -6
- package/dist/src/services/linear.js.map +1 -1
- package/dist/src/services/notion.d.ts +30 -0
- package/dist/src/services/notion.d.ts.map +1 -0
- package/dist/src/services/notion.js +121 -0
- package/dist/src/services/notion.js.map +1 -0
- package/dist/src/services/slack.d.ts +2 -0
- package/dist/src/services/slack.d.ts.map +1 -1
- package/dist/src/services/slack.js +3 -0
- package/dist/src/services/slack.js.map +1 -1
- package/dist/src/skillMd.d.ts +2 -0
- package/dist/src/skillMd.d.ts.map +1 -0
- package/dist/src/skillMd.js +19 -0
- package/dist/src/skillMd.js.map +1 -0
- package/dist/tests/cli.test.js +38 -1
- package/dist/tests/cli.test.js.map +1 -1
- package/dist/tests/registry.test.js +16 -3
- package/dist/tests/registry.test.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google service implementation with OAuth flow.
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import { ApiCredentialStatus, OAuthCredentials } from '../apiCredentials.js';
|
|
6
|
+
import { generateLatchkeyAppName, showSpinnerPage, withTempBrowserContext, } from '../playwrightUtils.js';
|
|
7
|
+
import { runCaptured } from '../curl.js';
|
|
8
|
+
import { exchangeCodeForTokens, refreshAccessToken, startOAuthCallbackServer, } from '../oauthUtils.js';
|
|
9
|
+
import { BrowserFollowupServiceSession, LoginFailedError, LoginCancelledError, isBrowserClosedError, } from './base.js';
|
|
10
|
+
const DEFAULT_TIMEOUT_MS = 8000;
|
|
11
|
+
const LOGIN_TIMEOUT_MS = 120000;
|
|
12
|
+
const GOOGLE_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token';
|
|
13
|
+
const APIS = [
|
|
14
|
+
'gmail.googleapis.com',
|
|
15
|
+
'calendar-json.googleapis.com',
|
|
16
|
+
'drive.googleapis.com',
|
|
17
|
+
'sheets.googleapis.com',
|
|
18
|
+
'docs.googleapis.com',
|
|
19
|
+
'people.googleapis.com', // Contacts API
|
|
20
|
+
];
|
|
21
|
+
const OAUTH_SCOPES = [
|
|
22
|
+
// User info (for credential validation)
|
|
23
|
+
'https://www.googleapis.com/auth/userinfo.profile',
|
|
24
|
+
'https://www.googleapis.com/auth/userinfo.email',
|
|
25
|
+
// Gmail API
|
|
26
|
+
'https://www.googleapis.com/auth/gmail.readonly',
|
|
27
|
+
'https://www.googleapis.com/auth/gmail.modify',
|
|
28
|
+
'https://www.googleapis.com/auth/gmail.compose',
|
|
29
|
+
'https://www.googleapis.com/auth/gmail.send',
|
|
30
|
+
// Calendar API
|
|
31
|
+
'https://www.googleapis.com/auth/calendar',
|
|
32
|
+
'https://www.googleapis.com/auth/calendar.events',
|
|
33
|
+
// Drive API
|
|
34
|
+
'https://www.googleapis.com/auth/drive',
|
|
35
|
+
'https://www.googleapis.com/auth/drive.file',
|
|
36
|
+
// Sheets API
|
|
37
|
+
'https://www.googleapis.com/auth/spreadsheets',
|
|
38
|
+
// Docs API
|
|
39
|
+
'https://www.googleapis.com/auth/documents',
|
|
40
|
+
// Contacts API
|
|
41
|
+
'https://www.googleapis.com/auth/contacts',
|
|
42
|
+
'https://www.googleapis.com/auth/contacts.readonly',
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Parse client_secret.json content.
|
|
46
|
+
*/
|
|
47
|
+
function parseClientSecretJson(content) {
|
|
48
|
+
try {
|
|
49
|
+
const json = JSON.parse(content);
|
|
50
|
+
const config = json.installed ?? json.web;
|
|
51
|
+
if (!config) {
|
|
52
|
+
throw new LoginFailedError('Invalid client_secret.json: missing "installed" or "web" configuration.');
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
clientId: config.client_id,
|
|
56
|
+
clientSecret: config.client_secret,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof LoginFailedError) {
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
throw new LoginFailedError(`Failed to parse client_secret.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function createProject(page) {
|
|
67
|
+
// Navigate to the projects page
|
|
68
|
+
await page.goto('https://console.cloud.google.com/projectselector2/home/dashboard', {
|
|
69
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
70
|
+
});
|
|
71
|
+
// Always create a new project
|
|
72
|
+
const createProjectButton = page.locator('.projectselector-project-create');
|
|
73
|
+
await createProjectButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
74
|
+
await createProjectButton.click();
|
|
75
|
+
const projectNameInput = page.locator('proj-name-id-input input');
|
|
76
|
+
await projectNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS * 100 });
|
|
77
|
+
await projectNameInput.fill(generateLatchkeyAppName());
|
|
78
|
+
const createButton = page.locator('button[type="submit"]');
|
|
79
|
+
await createButton.click();
|
|
80
|
+
await page.waitForURL('https://console.cloud.google.com/home/dashboard?project=**', {
|
|
81
|
+
timeout: 16000,
|
|
82
|
+
});
|
|
83
|
+
const urlObj = new URL(page.url());
|
|
84
|
+
const projectId = urlObj.searchParams.get('project');
|
|
85
|
+
if (!projectId) {
|
|
86
|
+
throw new LoginFailedError('Failed to create or retrieve Google Cloud project ID.');
|
|
87
|
+
}
|
|
88
|
+
return projectId;
|
|
89
|
+
}
|
|
90
|
+
async function enableApis(page, projectSlug) {
|
|
91
|
+
for (const api of APIS) {
|
|
92
|
+
await enableApi(page, projectSlug, api);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function enableApi(page, projectSlug, apiName) {
|
|
96
|
+
await page.goto(`https://console.cloud.google.com/apis/library/${apiName}?project=${projectSlug}`, {
|
|
97
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
98
|
+
});
|
|
99
|
+
const successIcon = page.locator('.cfc-icon-status-success'); // Present when API is already enabled.
|
|
100
|
+
const enableButton = page
|
|
101
|
+
.locator('.mp-details-cta-button-primary button .mdc-button__label')
|
|
102
|
+
.filter({ visible: true });
|
|
103
|
+
const sucessOrEnableButton = successIcon.or(enableButton);
|
|
104
|
+
await sucessOrEnableButton.isVisible({ timeout: DEFAULT_TIMEOUT_MS });
|
|
105
|
+
if (await successIcon.isVisible()) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
await enableButton.click();
|
|
109
|
+
const stopIndicator = page.locator('.cfc-icon-stop');
|
|
110
|
+
await stopIndicator.waitFor({ timeout: 18000 });
|
|
111
|
+
}
|
|
112
|
+
async function configureBranding(page, projectSlug) {
|
|
113
|
+
await page.goto(`https://console.cloud.google.com/auth/branding?project=${projectSlug}`, {
|
|
114
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
115
|
+
});
|
|
116
|
+
const getStartedButton = page.locator('cfc-empty-state-actions .mdc-button__label');
|
|
117
|
+
await getStartedButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
118
|
+
await getStartedButton.click();
|
|
119
|
+
const appNameInput = page.locator('input[formcontrolname="displayName"]');
|
|
120
|
+
await appNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
121
|
+
await appNameInput.fill(generateLatchkeyAppName());
|
|
122
|
+
const emailSelector = page.locator('svg[data-icon-name="arrowDropDownIcon"]').nth(0);
|
|
123
|
+
await emailSelector.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
124
|
+
await emailSelector.click();
|
|
125
|
+
const supportEmailOption = page.locator('mat-option > span:nth-child(1)').first();
|
|
126
|
+
await supportEmailOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
127
|
+
const supportEmailValue = await supportEmailOption.textContent();
|
|
128
|
+
await supportEmailOption.click();
|
|
129
|
+
const nextButton = page.locator('.cfc-stepper-step-button');
|
|
130
|
+
await nextButton.click();
|
|
131
|
+
const internalAudienceRadio = page.locator('.mdc-radio').nth(0);
|
|
132
|
+
await internalAudienceRadio.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
133
|
+
await internalAudienceRadio.click();
|
|
134
|
+
await nextButton.click();
|
|
135
|
+
const contactEmailInput = page.locator('mat-chip-grid[formcontrolname="emails"] input');
|
|
136
|
+
await contactEmailInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
137
|
+
await contactEmailInput.fill(supportEmailValue ?? '');
|
|
138
|
+
await nextButton.click();
|
|
139
|
+
const agreeCheckbox = page.locator('input[type="checkbox"]');
|
|
140
|
+
await agreeCheckbox.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
141
|
+
await agreeCheckbox.click();
|
|
142
|
+
await nextButton.click();
|
|
143
|
+
const createButton = page.locator('.cfc-stepper-submit-button button');
|
|
144
|
+
await createButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
145
|
+
await createButton.click();
|
|
146
|
+
}
|
|
147
|
+
async function createOAuthClient(page) {
|
|
148
|
+
// Navigate to credentials page
|
|
149
|
+
await page.goto('https://console.cloud.google.com/apis/credentials', {
|
|
150
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
151
|
+
});
|
|
152
|
+
// Click "Create Credentials" button
|
|
153
|
+
const createCredentialsButton = page.locator('services-create-credentials-menu button');
|
|
154
|
+
await createCredentialsButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
155
|
+
await createCredentialsButton.click();
|
|
156
|
+
// Click "OAuth client ID"
|
|
157
|
+
const oauthClientIdOption = page.locator('cfc-menu-item[track-metadata-type="OAUTH_CLIENT"]');
|
|
158
|
+
await oauthClientIdOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
159
|
+
await oauthClientIdOption.click();
|
|
160
|
+
const applicationTypeDropdown = page.locator('svg[data-icon-name="arrowDropDownIcon"]').nth(0);
|
|
161
|
+
await applicationTypeDropdown.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
162
|
+
await applicationTypeDropdown.click();
|
|
163
|
+
const desktopAppOption = page.locator('#_1rif_mat-option-5');
|
|
164
|
+
await desktopAppOption.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
165
|
+
await desktopAppOption.click();
|
|
166
|
+
const clientNameInput = page.locator('input[formcontrolname="displayName"]');
|
|
167
|
+
await clientNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
168
|
+
await clientNameInput.fill(generateLatchkeyAppName());
|
|
169
|
+
// Click Create
|
|
170
|
+
const createButton = page.locator('cfc-progress-button button');
|
|
171
|
+
await createButton.click();
|
|
172
|
+
// Download the JSON file
|
|
173
|
+
const downloadButton = page.locator('cfc-icon[icon="download"]');
|
|
174
|
+
await downloadButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
175
|
+
const [download] = await Promise.all([page.waitForEvent('download'), downloadButton.click()]);
|
|
176
|
+
const path = await download.path();
|
|
177
|
+
if (!path) {
|
|
178
|
+
throw new LoginFailedError('Failed to download client_secret.json');
|
|
179
|
+
}
|
|
180
|
+
const content = await fs.readFile(path, 'utf-8');
|
|
181
|
+
return parseClientSecretJson(content);
|
|
182
|
+
}
|
|
183
|
+
function checkGoogleLoginResponse(response, loginDetector) {
|
|
184
|
+
if (loginDetector.isLoggedIn) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const request = response.request();
|
|
188
|
+
// Detect successful login by checking for Google account access
|
|
189
|
+
if (request.url().startsWith('https://console.cloud.google.com/')) {
|
|
190
|
+
if (response.status() === 200) {
|
|
191
|
+
void response.text().then((text) => {
|
|
192
|
+
// Check if we're actually logged in (not on login page)
|
|
193
|
+
if (!text.includes('accounts.google.com/signin')) {
|
|
194
|
+
loginDetector.isLoggedIn = true;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async function waitForGoogleLogin(page) {
|
|
201
|
+
const loginDetector = { isLoggedIn: false };
|
|
202
|
+
const responseHandler = (response) => {
|
|
203
|
+
checkGoogleLoginResponse(response, loginDetector);
|
|
204
|
+
};
|
|
205
|
+
page.on('response', responseHandler);
|
|
206
|
+
while (!loginDetector.isLoggedIn) {
|
|
207
|
+
await page.waitForTimeout(100);
|
|
208
|
+
}
|
|
209
|
+
page.off('response', responseHandler);
|
|
210
|
+
}
|
|
211
|
+
class GoogleServiceSession extends BrowserFollowupServiceSession {
|
|
212
|
+
loginDetector = { isLoggedIn: false };
|
|
213
|
+
onResponse(response) {
|
|
214
|
+
checkGoogleLoginResponse(response, this.loginDetector);
|
|
215
|
+
}
|
|
216
|
+
isLoginComplete() {
|
|
217
|
+
return this.loginDetector.isLoggedIn;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Override to skip the spinner page since the OAuth flow requires user interaction
|
|
221
|
+
* (granting consent on Google's authorization page).
|
|
222
|
+
*/
|
|
223
|
+
finalizeCredentials(_browser, context, oldCredentials) {
|
|
224
|
+
return this.performBrowserFollowup(context, oldCredentials);
|
|
225
|
+
}
|
|
226
|
+
async performBrowserFollowup(context, oldCredentials) {
|
|
227
|
+
const page = context.pages()[0];
|
|
228
|
+
if (!page) {
|
|
229
|
+
throw new LoginFailedError('No page available in browser context.');
|
|
230
|
+
}
|
|
231
|
+
// Require existing credentials with client ID and secret
|
|
232
|
+
if (!(oldCredentials instanceof OAuthCredentials)) {
|
|
233
|
+
throw new LoginFailedError('Google login requires existing OAuth client credentials. Run prepare first.');
|
|
234
|
+
}
|
|
235
|
+
const clientId = oldCredentials.clientId;
|
|
236
|
+
const clientSecret = oldCredentials.clientSecret;
|
|
237
|
+
// Perform OAuth flow with localhost server
|
|
238
|
+
const { accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt } = await this.performOAuthFlow(context, page, clientId, clientSecret);
|
|
239
|
+
await page.close();
|
|
240
|
+
return new OAuthCredentials(clientId, clientSecret, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt);
|
|
241
|
+
}
|
|
242
|
+
async performOAuthFlow(context, page, clientId, clientSecret) {
|
|
243
|
+
// Use an AbortController to signal the OAuth callback server to shut down
|
|
244
|
+
// when the browser is closed. Listen to both page and context close events
|
|
245
|
+
// to handle all cases where the user might close the browser.
|
|
246
|
+
const abortController = new AbortController();
|
|
247
|
+
const closeHandler = () => {
|
|
248
|
+
abortController.abort();
|
|
249
|
+
};
|
|
250
|
+
page.on('close', closeHandler);
|
|
251
|
+
context.on('close', closeHandler);
|
|
252
|
+
try {
|
|
253
|
+
// Start the callback server first to get the auto-assigned port
|
|
254
|
+
const { port, codePromise } = await startOAuthCallbackServer(LOGIN_TIMEOUT_MS, abortController.signal);
|
|
255
|
+
const redirectUri = `http://localhost:${port.toString()}/oauth2callback`;
|
|
256
|
+
const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
|
|
257
|
+
authUrl.searchParams.set('client_id', clientId);
|
|
258
|
+
authUrl.searchParams.set('redirect_uri', redirectUri);
|
|
259
|
+
authUrl.searchParams.set('response_type', 'code');
|
|
260
|
+
authUrl.searchParams.set('scope', OAUTH_SCOPES.join(' '));
|
|
261
|
+
authUrl.searchParams.set('access_type', 'offline');
|
|
262
|
+
authUrl.searchParams.set('prompt', 'consent');
|
|
263
|
+
await page.goto(authUrl.toString());
|
|
264
|
+
// Wait for the authorization code from the callback
|
|
265
|
+
const code = await codePromise;
|
|
266
|
+
const tokens = exchangeCodeForTokens(GOOGLE_TOKEN_ENDPOINT, code, clientId, clientSecret, redirectUri);
|
|
267
|
+
const accessTokenExpiresAt = new Date(Date.now() + tokens.expires_in * 1000).toISOString();
|
|
268
|
+
// Google refresh tokens typically don't expire, so we don't set refreshTokenExpiresAt
|
|
269
|
+
return {
|
|
270
|
+
accessToken: tokens.access_token,
|
|
271
|
+
refreshToken: tokens.refresh_token,
|
|
272
|
+
accessTokenExpiresAt,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
if (error instanceof Error && isBrowserClosedError(error)) {
|
|
277
|
+
throw new LoginCancelledError();
|
|
278
|
+
}
|
|
279
|
+
throw error;
|
|
280
|
+
}
|
|
281
|
+
finally {
|
|
282
|
+
// Remove the close handlers to prevent them from firing when context
|
|
283
|
+
// is closed normally during cleanup
|
|
284
|
+
page.off('close', closeHandler);
|
|
285
|
+
context.off('close', closeHandler);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
export class Google {
|
|
290
|
+
name = 'google';
|
|
291
|
+
displayName = 'Google Workspace';
|
|
292
|
+
baseApiUrls = ['https://www.googleapis.com/'];
|
|
293
|
+
loginUrl = 'https://console.cloud.google.com/';
|
|
294
|
+
info = 'Supports some Google Workspace APIs: Gmail, Calendar, Drive, Sheets, Docs, and Contacts. ' +
|
|
295
|
+
'If needed, run "latchkey prepare google" to create an OAuth client first. ' +
|
|
296
|
+
'It may take a few minutes before the OAuth client is ready to use.';
|
|
297
|
+
credentialCheckCurlArguments = [
|
|
298
|
+
'https://www.googleapis.com/oauth2/v1/userinfo',
|
|
299
|
+
];
|
|
300
|
+
getSession() {
|
|
301
|
+
return new GoogleServiceSession(this);
|
|
302
|
+
}
|
|
303
|
+
checkApiCredentials(apiCredentials) {
|
|
304
|
+
if (!(apiCredentials instanceof OAuthCredentials)) {
|
|
305
|
+
return ApiCredentialStatus.Invalid;
|
|
306
|
+
}
|
|
307
|
+
// Credentials from prepare() don't have tokens yet
|
|
308
|
+
if (apiCredentials.accessToken === undefined) {
|
|
309
|
+
return ApiCredentialStatus.Missing;
|
|
310
|
+
}
|
|
311
|
+
const result = runCaptured([
|
|
312
|
+
'-s',
|
|
313
|
+
'-o',
|
|
314
|
+
'/dev/null',
|
|
315
|
+
'-w',
|
|
316
|
+
'%{http_code}',
|
|
317
|
+
...apiCredentials.asCurlArguments(),
|
|
318
|
+
...this.credentialCheckCurlArguments,
|
|
319
|
+
], 10);
|
|
320
|
+
if (result.stdout === '200') {
|
|
321
|
+
return ApiCredentialStatus.Valid;
|
|
322
|
+
}
|
|
323
|
+
return ApiCredentialStatus.Invalid;
|
|
324
|
+
}
|
|
325
|
+
async prepare(encryptedStorage, launchOptions) {
|
|
326
|
+
return withTempBrowserContext(encryptedStorage, launchOptions ?? {}, async ({ context }) => {
|
|
327
|
+
const page = await context.newPage();
|
|
328
|
+
await page.goto(this.loginUrl);
|
|
329
|
+
await waitForGoogleLogin(page);
|
|
330
|
+
await showSpinnerPage(context, `Finalizing ${this.displayName} login...\nThis can take a few minutes.`);
|
|
331
|
+
const projectSlug = await createProject(page);
|
|
332
|
+
await enableApis(page, projectSlug);
|
|
333
|
+
await configureBranding(page, projectSlug);
|
|
334
|
+
const { clientId, clientSecret } = await createOAuthClient(page);
|
|
335
|
+
await page.close();
|
|
336
|
+
return new OAuthCredentials(clientId, clientSecret);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
refreshCredentials(apiCredentials) {
|
|
340
|
+
if (!(apiCredentials instanceof OAuthCredentials)) {
|
|
341
|
+
return Promise.resolve(null);
|
|
342
|
+
}
|
|
343
|
+
if (!apiCredentials.refreshToken) {
|
|
344
|
+
return Promise.resolve(null);
|
|
345
|
+
}
|
|
346
|
+
const tokens = refreshAccessToken(GOOGLE_TOKEN_ENDPOINT, apiCredentials.refreshToken, apiCredentials.clientId, apiCredentials.clientSecret);
|
|
347
|
+
if (tokens === null) {
|
|
348
|
+
return Promise.resolve(null);
|
|
349
|
+
}
|
|
350
|
+
// Calculate access token expiration from the expires_in field
|
|
351
|
+
const accessTokenExpiresAt = new Date(Date.now() + tokens.expires_in * 1000).toISOString();
|
|
352
|
+
// Return new credentials with refreshed access token
|
|
353
|
+
// Keep the same refresh token unless a new one is provided
|
|
354
|
+
return Promise.resolve(new OAuthCredentials(apiCredentials.clientId, apiCredentials.clientSecret, tokens.access_token, tokens.refresh_token, accessTokenExpiresAt, apiCredentials.refreshTokenExpiresAt));
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
export const GOOGLE = new Google();
|
|
358
|
+
//# sourceMappingURL=google.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/services/google.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,4 +9,6 @@ export { Discord, DISCORD } from './discord.js';
|
|
|
9
9
|
export { Github, GITHUB } from './github.js';
|
|
10
10
|
export { Dropbox, DROPBOX } from './dropbox.js';
|
|
11
11
|
export { Linear, LINEAR } from './linear.js';
|
|
12
|
+
export { Google, GOOGLE } from './google.js';
|
|
13
|
+
export { Notion, NOTION } from './notion.js';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -8,4 +8,6 @@ export { Discord, DISCORD } from './discord.js';
|
|
|
8
8
|
export { Github, GITHUB } from './github.js';
|
|
9
9
|
export { Dropbox, DROPBOX } from './dropbox.js';
|
|
10
10
|
export { Linear, LINEAR } from './linear.js';
|
|
11
|
+
export { Google, GOOGLE } from './google.js';
|
|
12
|
+
export { Notion, NOTION } from './notion.js';
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -8,12 +8,14 @@ declare class LinearServiceSession extends BrowserFollowupServiceSession {
|
|
|
8
8
|
private isLoggedIn;
|
|
9
9
|
onResponse(response: Response): void;
|
|
10
10
|
protected isLoginComplete(): boolean;
|
|
11
|
-
protected performBrowserFollowup(context: BrowserContext): Promise<ApiCredentials | null>;
|
|
11
|
+
protected performBrowserFollowup(context: BrowserContext, _oldCredentials?: ApiCredentials): Promise<ApiCredentials | null>;
|
|
12
12
|
}
|
|
13
13
|
export declare class Linear implements Service {
|
|
14
14
|
readonly name = "linear";
|
|
15
|
+
readonly displayName = "Linear";
|
|
15
16
|
readonly baseApiUrls: readonly ["https://api.linear.app/"];
|
|
16
17
|
readonly loginUrl = "https://linear.app/imbue/settings/account/security/api-keys/new";
|
|
18
|
+
readonly info = "https://linear.app/developers/graphql";
|
|
17
19
|
readonly credentialCheckCurlArguments: readonly ["-X", "POST", "-H", "Content-Type: application/json", "-d", "{\"query\": \"{ viewer { id } }\"}", "https://api.linear.app/graphql"];
|
|
18
20
|
getSession(): LinearServiceSession;
|
|
19
21
|
checkApiCredentials(apiCredentials: ApiCredentials): ApiCredentialStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../../src/services/linear.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../../src/services/linear.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAqB,MAAM,sBAAsB,CAAC;AAG9F,OAAO,EAAE,OAAO,EAAE,6BAA6B,EAAoB,MAAM,WAAW,CAAC;AAOrF,cAAM,oBAAqB,SAAQ,6BAA6B;IAC9D,OAAO,CAAC,UAAU,CAAS;IAE3B,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IA+BpC,SAAS,CAAC,eAAe,IAAI,OAAO;cAIpB,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,eAAe,CAAC,EAAE,cAAc,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAgClC;AAED,qBAAa,MAAO,YAAW,OAAO;IACpC,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,YAAY;IAChC,QAAQ,CAAC,WAAW,uCAAwC;IAC5D,QAAQ,CAAC,QAAQ,qEAA0B;IAC3C,QAAQ,CAAC,IAAI,2CAA2C;IAExD,QAAQ,CAAC,4BAA4B,gJAQ1B;IAEX,UAAU,IAAI,oBAAoB;IAIlC,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,mBAAmB;CAwBzE;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Linear service implementation.
|
|
3
3
|
*/
|
|
4
|
-
import { randomUUID } from 'node:crypto';
|
|
5
4
|
import { ApiCredentialStatus, AuthorizationBare } from '../apiCredentials.js';
|
|
6
5
|
import { runCaptured } from '../curl.js';
|
|
7
|
-
import { typeLikeHuman } from '../playwrightUtils.js';
|
|
6
|
+
import { generateLatchkeyAppName, typeLikeHuman } from '../playwrightUtils.js';
|
|
8
7
|
import { BrowserFollowupServiceSession, LoginFailedError } from './base.js';
|
|
9
8
|
const DEFAULT_TIMEOUT_MS = 8000;
|
|
10
9
|
// URL for creating a new personal API key (also used as login URL)
|
|
@@ -44,19 +43,19 @@ class LinearServiceSession extends BrowserFollowupServiceSession {
|
|
|
44
43
|
isLoginComplete() {
|
|
45
44
|
return this.isLoggedIn;
|
|
46
45
|
}
|
|
47
|
-
async performBrowserFollowup(context) {
|
|
46
|
+
async performBrowserFollowup(context, _oldCredentials) {
|
|
48
47
|
const page = context.pages()[0];
|
|
49
48
|
if (!page) {
|
|
50
49
|
throw new LoginFailedError('No page available in browser context.');
|
|
51
50
|
}
|
|
52
51
|
await page.goto(LINEAR_NEW_API_KEY_URL);
|
|
53
52
|
// Fill in the key name
|
|
54
|
-
const keyName =
|
|
55
|
-
const keyNameInput = page.
|
|
53
|
+
const keyName = generateLatchkeyAppName();
|
|
54
|
+
const keyNameInput = page.locator('//*[@id="label"]');
|
|
56
55
|
await keyNameInput.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
57
56
|
await typeLikeHuman(page, keyNameInput, keyName);
|
|
58
57
|
// Click the Create button
|
|
59
|
-
const createButton = page.
|
|
58
|
+
const createButton = page.locator('button[type="submit"]');
|
|
60
59
|
await createButton.waitFor({ timeout: DEFAULT_TIMEOUT_MS });
|
|
61
60
|
await createButton.click();
|
|
62
61
|
// Wait for and extract the token from span element containing lin_api_ prefix
|
|
@@ -72,8 +71,10 @@ class LinearServiceSession extends BrowserFollowupServiceSession {
|
|
|
72
71
|
}
|
|
73
72
|
export class Linear {
|
|
74
73
|
name = 'linear';
|
|
74
|
+
displayName = 'Linear';
|
|
75
75
|
baseApiUrls = ['https://api.linear.app/'];
|
|
76
76
|
loginUrl = LINEAR_NEW_API_KEY_URL;
|
|
77
|
+
info = 'https://linear.app/developers/graphql';
|
|
77
78
|
credentialCheckCurlArguments = [
|
|
78
79
|
'-X',
|
|
79
80
|
'POST',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linear.js","sourceRoot":"","sources":["../../../src/services/linear.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"linear.js","sourceRoot":"","sources":["../../../src/services/linear.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notion service implementation.
|
|
3
|
+
*
|
|
4
|
+
* This has some severe limitations:
|
|
5
|
+
*
|
|
6
|
+
* - It requires the UI to be in English.
|
|
7
|
+
* - It only grants access to the private pages that existed at the time of login.
|
|
8
|
+
*/
|
|
9
|
+
import type { Response, BrowserContext } from 'playwright';
|
|
10
|
+
import { ApiCredentialStatus, ApiCredentials } from '../apiCredentials.js';
|
|
11
|
+
import { Service, BrowserFollowupServiceSession } from './base.js';
|
|
12
|
+
declare class NotionServiceSession extends BrowserFollowupServiceSession {
|
|
13
|
+
private isLoggedIn;
|
|
14
|
+
onResponse(response: Response): void;
|
|
15
|
+
protected isLoginComplete(): boolean;
|
|
16
|
+
protected performBrowserFollowup(context: BrowserContext): Promise<ApiCredentials | null>;
|
|
17
|
+
}
|
|
18
|
+
export declare class Notion implements Service {
|
|
19
|
+
readonly name = "notion";
|
|
20
|
+
readonly displayName = "Notion";
|
|
21
|
+
readonly baseApiUrls: readonly ["https://api.notion.com/"];
|
|
22
|
+
readonly loginUrl = "https://www.notion.so/profile/integrations/form/new-integration";
|
|
23
|
+
readonly info: string;
|
|
24
|
+
readonly credentialCheckCurlArguments: readonly ["-H", "Notion-Version: 2022-06-28", "https://api.notion.com/v1/users/me"];
|
|
25
|
+
getSession(): NotionServiceSession;
|
|
26
|
+
checkApiCredentials(apiCredentials: ApiCredentials): ApiCredentialStatus;
|
|
27
|
+
}
|
|
28
|
+
export declare const NOTION: Notion;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=notion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notion.d.ts","sourceRoot":"","sources":["../../../src/services/notion.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAuB,MAAM,sBAAsB,CAAC;AAGhG,OAAO,EAAE,OAAO,EAAE,6BAA6B,EAAoB,MAAM,WAAW,CAAC;AAMrF,cAAM,oBAAqB,SAAQ,6BAA6B;IAC9D,OAAO,CAAC,UAAU,CAAS;IAE3B,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IASpC,SAAS,CAAC,eAAe,IAAI,OAAO;cAIpB,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;CAgEhG;AAED,qBAAa,MAAO,YAAW,OAAO;IACpC,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,YAAY;IAChC,QAAQ,CAAC,WAAW,uCAAwC;IAC5D,QAAQ,CAAC,QAAQ,qEAA2B;IAC5C,QAAQ,CAAC,IAAI,SAG2E;IAExF,QAAQ,CAAC,4BAA4B,sFAI1B;IAEX,UAAU,IAAI,oBAAoB;IAIlC,mBAAmB,CAAC,cAAc,EAAE,cAAc,GAAG,mBAAmB;CAuBzE;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}
|