signicat-client-ts
Version:
Community TypeScript client for Signicat Authentication REST API with automatic token management
107 lines (106 loc) • 4.31 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenManager = void 0;
const axios_1 = __importDefault(require("axios"));
class TokenManager {
constructor(options) {
this.currentToken = null;
this.expiresAt = 0;
this.isRefreshing = false;
this.refreshPromise = null;
this.clientId = options.clientId;
this.clientSecret = options.clientSecret;
this.tokenUrl = options.tokenUrl || "https://api.signicat.com/auth/open/connect/token";
this.scope = options.scope || "signicat-api";
this.expirationBuffer = options.expirationBuffer || 60; // default 60 seconds
}
/**
* get a valid access token
* if the token does not exist or has expired or is about to expire, get a new token
*/
getToken() {
return __awaiter(this, void 0, void 0, function* () {
// if the token exists and is still valid
if (this.currentToken && this.expiresAt > Date.now() + this.expirationBuffer * 1000) {
return this.currentToken;
}
// if a refresh is already in progress, return the ongoing request
if (this.isRefreshing && this.refreshPromise) {
return this.refreshPromise;
}
// request a new token
this.isRefreshing = true;
this.refreshPromise = this.fetchNewToken().finally(() => {
this.isRefreshing = false;
this.refreshPromise = null;
});
return this.refreshPromise;
});
}
/**
* get a new access token
*/
fetchNewToken() {
return __awaiter(this, void 0, void 0, function* () {
try {
const formData = new URLSearchParams();
formData.append("grant_type", "client_credentials");
formData.append("scope", this.scope);
formData.append("client_id", this.clientId);
formData.append("client_secret", this.clientSecret);
const response = yield axios_1.default.post(this.tokenUrl, formData.toString(), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
const { access_token, expires_in } = response.data;
// save the token and calculate the expiration time
this.currentToken = access_token;
this.expiresAt = Date.now() + expires_in * 1000;
return access_token;
}
catch (error) {
console.error("Failed to fetch access token:", error);
throw error;
}
});
}
/**
* 토큰을 강제로 갱신합니다.
* force refresh the token
*/
refreshToken() {
return __awaiter(this, void 0, void 0, function* () {
this.currentToken = null;
this.expiresAt = 0;
return this.getToken();
});
}
/**
* 현재 토큰의 만료 시간을 확인합니다.
* check the expiration time of the current token
*/
getTokenExpiresAt() {
return this.expiresAt;
}
/**
* 토큰이 유효한지 확인합니다.
* check if the token is valid
*/
isTokenValid() {
return !!this.currentToken && this.expiresAt > Date.now();
}
}
exports.TokenManager = TokenManager;