repowise 0.1.65 → 0.1.67
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/dist/bin/repowise.js +54 -17
- package/package.json +1 -1
package/dist/bin/repowise.js
CHANGED
|
@@ -228,16 +228,23 @@ async function storeCredentials(credentials) {
|
|
|
228
228
|
await writeFile3(CREDENTIALS_PATH, JSON.stringify(credentials, null, 2));
|
|
229
229
|
await chmod3(CREDENTIALS_PATH, 384);
|
|
230
230
|
}
|
|
231
|
-
async function getValidCredentials() {
|
|
231
|
+
async function getValidCredentials(options) {
|
|
232
232
|
const creds = await getStoredCredentials();
|
|
233
233
|
if (!creds)
|
|
234
234
|
return null;
|
|
235
|
-
|
|
235
|
+
const now = Date.now();
|
|
236
|
+
const needsRefresh = options?.forceRefresh || now > creds.expiresAt - 5 * 60 * 1e3;
|
|
237
|
+
if (needsRefresh) {
|
|
236
238
|
try {
|
|
237
239
|
const refreshed = await refreshTokens(creds.refreshToken, creds);
|
|
238
240
|
await storeCredentials(refreshed);
|
|
239
241
|
return refreshed;
|
|
240
|
-
} catch {
|
|
242
|
+
} catch (err) {
|
|
243
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
244
|
+
console.warn(`Token refresh failed: ${message}`);
|
|
245
|
+
if (now < creds.expiresAt) {
|
|
246
|
+
return creds;
|
|
247
|
+
}
|
|
241
248
|
return null;
|
|
242
249
|
}
|
|
243
250
|
}
|
|
@@ -269,24 +276,40 @@ var PollClient = class {
|
|
|
269
276
|
if (options?.includeActiveRepos) {
|
|
270
277
|
params.set("includeActiveRepos", "true");
|
|
271
278
|
}
|
|
279
|
+
const url = `${this.apiUrl}/v1/listeners/poll?${params.toString()}`;
|
|
280
|
+
const result = await this.fetchWithAuth(url, credentials.accessToken);
|
|
281
|
+
if (result.status === 401 || result.status === 403) {
|
|
282
|
+
const refreshed = await getValidCredentials({ forceRefresh: true });
|
|
283
|
+
if (!refreshed) {
|
|
284
|
+
throw new AuthError("Session expired. Run `repowise login` again.");
|
|
285
|
+
}
|
|
286
|
+
const retry = await this.fetchWithAuth(url, refreshed.accessToken);
|
|
287
|
+
if (retry.status === 401 || retry.status === 403) {
|
|
288
|
+
throw new AuthError("Session expired. Run `repowise login` again.");
|
|
289
|
+
}
|
|
290
|
+
if (!retry.ok) {
|
|
291
|
+
throw new Error(`Poll request failed: ${retry.status}`);
|
|
292
|
+
}
|
|
293
|
+
const json2 = await retry.json();
|
|
294
|
+
return json2.data;
|
|
295
|
+
}
|
|
296
|
+
if (!result.ok) {
|
|
297
|
+
throw new Error(`Poll request failed: ${result.status}`);
|
|
298
|
+
}
|
|
299
|
+
const json = await result.json();
|
|
300
|
+
return json.data;
|
|
301
|
+
}
|
|
302
|
+
async fetchWithAuth(url, accessToken) {
|
|
272
303
|
const controller = new AbortController();
|
|
273
304
|
const timeoutId = setTimeout(() => controller.abort(), POLL_TIMEOUT_MS);
|
|
274
305
|
try {
|
|
275
|
-
|
|
306
|
+
return await fetch(url, {
|
|
276
307
|
headers: {
|
|
277
|
-
Authorization: `Bearer ${
|
|
308
|
+
Authorization: `Bearer ${accessToken}`,
|
|
278
309
|
"Content-Type": "application/json"
|
|
279
310
|
},
|
|
280
311
|
signal: controller.signal
|
|
281
312
|
});
|
|
282
|
-
if (response.status === 401 || response.status === 403) {
|
|
283
|
-
throw new AuthError("Session expired. Run `repowise login` again.");
|
|
284
|
-
}
|
|
285
|
-
if (!response.ok) {
|
|
286
|
-
throw new Error(`Poll request failed: ${response.status}`);
|
|
287
|
-
}
|
|
288
|
-
const json = await response.json();
|
|
289
|
-
return json.data;
|
|
290
313
|
} finally {
|
|
291
314
|
clearTimeout(timeoutId);
|
|
292
315
|
}
|
|
@@ -757,7 +780,22 @@ async function startListener(options) {
|
|
|
757
780
|
}
|
|
758
781
|
}
|
|
759
782
|
if (anyAuthError) {
|
|
760
|
-
|
|
783
|
+
let recovered = false;
|
|
784
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
785
|
+
console.warn(`Auth error \u2014 retrying credentials (attempt ${attempt}/3)...`);
|
|
786
|
+
await sleep(5e3);
|
|
787
|
+
if (!running)
|
|
788
|
+
break;
|
|
789
|
+
const fresh = await getValidCredentials({ forceRefresh: true });
|
|
790
|
+
if (fresh) {
|
|
791
|
+
console.log("Credentials recovered \u2014 resuming listener");
|
|
792
|
+
recovered = true;
|
|
793
|
+
break;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
if (recovered)
|
|
797
|
+
continue;
|
|
798
|
+
console.error("Session expired after 3 retries. Sending notification email and waiting for re-authentication...");
|
|
761
799
|
const creds = await getStoredCredentials();
|
|
762
800
|
const email = creds?.idToken ? decodeEmailFromIdToken(creds.idToken) : null;
|
|
763
801
|
if (email && authErrorGroup) {
|
|
@@ -774,7 +812,7 @@ async function startListener(options) {
|
|
|
774
812
|
await sleep(5 * 60 * 1e3);
|
|
775
813
|
if (!running)
|
|
776
814
|
break;
|
|
777
|
-
const fresh = await getValidCredentials();
|
|
815
|
+
const fresh = await getValidCredentials({ forceRefresh: true });
|
|
778
816
|
if (fresh) {
|
|
779
817
|
console.log("Re-authenticated \u2014 resuming listener");
|
|
780
818
|
break;
|
|
@@ -806,8 +844,7 @@ function isStagingMode() {
|
|
|
806
844
|
var PRODUCTION = {
|
|
807
845
|
apiUrl: "https://api.repowise.ai",
|
|
808
846
|
cognitoDomain: "auth-repowise",
|
|
809
|
-
cognitoClientId: "",
|
|
810
|
-
// TODO: set after production Cognito deploy
|
|
847
|
+
cognitoClientId: "50so1fkmjbqt1ufnsmbhsjbtst",
|
|
811
848
|
cognitoRegion: "us-east-1",
|
|
812
849
|
customDomain: false
|
|
813
850
|
};
|