MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / refreshOAuthConnection

Function refreshOAuthConnection

apps/cli/src/main.ts:758–812  ·  view source on GitHub ↗
(
  connection: ExecutorServerConnection,
)

Source from the content-addressed store, hash-verified

756const OAUTH_REFRESH_SKEW_SECONDS = 60;
757
758const refreshOAuthConnection = (
759 connection: ExecutorServerConnection,
760): Effect.Effect<ExecutorServerConnection, Error, FileSystem.FileSystem | PlatformPath.Path> =>
761 Effect.gen(function* () {
762 const auth = connection.auth;
763 if (!auth || auth.kind !== "oauth") return connection;
764 const now = Math.floor(Date.now() / 1000);
765 if (auth.expiresAt && auth.expiresAt - now > OAUTH_REFRESH_SKEW_SECONDS) return connection;
766 // Destructure so the narrowed string types survive into the deferred
767 // `tryPromise` callback (where TS would otherwise re-widen the fields).
768 const { refreshToken, tokenEndpoint, clientId } = auth;
769 if (!refreshToken || !tokenEndpoint || !clientId) return connection;
770
771 const headers = yield* resolveExecutorServerConfiguredHeaders(connection, process.env).pipe(
772 Effect.mapError(toError),
773 );
774
775 const refreshed = yield* Effect.tryPromise({
776 try: () =>
777 refreshDeviceTokens({
778 tokenEndpoint,
779 clientId,
780 refreshToken,
781 serverOrigin: connection.origin,
782 headers,
783 }),
784 catch: toError,
785 // On a failed refresh, keep the existing token and let the eventual 401
786 // surface, better than blocking the command on a transient hiccup.
787 }).pipe(Effect.option);
788 if (Option.isNone(refreshed)) return connection;
789
790 const next = refreshed.value;
791 const nextConnection = normalizeExecutorServerConnection({
792 ...connection,
793 auth: {
794 kind: "oauth",
795 accessToken: next.accessToken,
796 refreshToken: next.refreshToken ?? refreshToken,
797 ...(next.expiresAt ? { expiresAt: next.expiresAt } : {}),
798 tokenEndpoint,
799 clientId,
800 },
801 });
802
803 const profileName = profileNameFromConnectionKey(connection.key);
804 if (profileName) {
805 yield* upsertCliServerConnectionProfile({
806 name: profileName,
807 connection: nextConnection,
808 makeDefault: false,
809 }).pipe(Effect.ignore);
810 }
811 return nextConnection;
812 });
813
814const resolveExecutorServerConnection = (
815 target: ServerTarget,

Callers 2

main.tsFile · 0.85

Tested by

no test coverage detected