mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-10-15 05:11:26 +00:00
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:
@@ -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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user