fix(gitlab): share one token refresh between concurrent callers

GitLab invalidates a refresh token when it is used. Two deployments that found the token expired at the same time sent the same refresh token, and the second one failed with "Failed to refresh token: Bad Request".
This commit is contained in:
ahmedisam99
2026-10-12 11:54:35 +03:00
parent 5be17d3dd0
commit 412516d47b
+18 -1
View File
@@ -11,7 +11,7 @@ import { TRPCError } from "@trpc/server";
import { quote } from "shell-quote";
import type { z } from "zod";
export const refreshGitlabToken = async (gitlabProviderId: string) => {
const refreshGitlabTokenIfExpired = async (gitlabProviderId: string) => {
const gitlabProvider = await findGitlabById(gitlabProviderId);
const currentTime = Math.floor(Date.now() / 1000);
@@ -56,6 +56,23 @@ export const refreshGitlabToken = async (gitlabProviderId: string) => {
return data;
};
// GitLab invalidates a refresh token when it is used, so concurrent callers must share one refresh
const pendingRefreshes = new Map<
string,
ReturnType<typeof refreshGitlabTokenIfExpired>
>();
export const refreshGitlabToken = (gitlabProviderId: string) => {
let refresh = pendingRefreshes.get(gitlabProviderId);
if (!refresh) {
refresh = refreshGitlabTokenIfExpired(gitlabProviderId).finally(() => {
pendingRefreshes.delete(gitlabProviderId);
});
pendingRefreshes.set(gitlabProviderId, refresh);
}
return refresh;
};
export const haveGitlabRequirements = (gitlabProvider: Gitlab) => {
return !!(gitlabProvider?.accessToken && gitlabProvider?.refreshToken);
};