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

Function refreshOAuthConnection

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

Source from the content-addressed store, hash-verified

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

Callers 2

main.tsFile · 0.85

Tested by

no test coverage detected