connectbase-client 6.0.0 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/connect-base.umd.js +5 -5
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +50 -0
- package/dist/index.mjs +50 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -329,6 +329,11 @@ declare class HttpClient {
|
|
|
329
329
|
private markSessionHint;
|
|
330
330
|
private clearSessionHint;
|
|
331
331
|
private hasSessionHint;
|
|
332
|
+
private buildNoCookieSessionKey;
|
|
333
|
+
private markNoCookieSession;
|
|
334
|
+
private clearNoCookieSessionMark;
|
|
335
|
+
/** 쿠키 전용 refresh 를 지금 건너뛰어야 하는지 (최근에 401/403 을 받았는지). */
|
|
336
|
+
private isNoCookieSessionMarkFresh;
|
|
332
337
|
/**
|
|
333
338
|
* OAuth redirect callback 직후 호출되어 HttpOnly cookie 를 부트스트랩한다.
|
|
334
339
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -329,6 +329,11 @@ declare class HttpClient {
|
|
|
329
329
|
private markSessionHint;
|
|
330
330
|
private clearSessionHint;
|
|
331
331
|
private hasSessionHint;
|
|
332
|
+
private buildNoCookieSessionKey;
|
|
333
|
+
private markNoCookieSession;
|
|
334
|
+
private clearNoCookieSessionMark;
|
|
335
|
+
/** 쿠키 전용 refresh 를 지금 건너뛰어야 하는지 (최근에 401/403 을 받았는지). */
|
|
336
|
+
private isNoCookieSessionMarkFresh;
|
|
332
337
|
/**
|
|
333
338
|
* OAuth redirect callback 직후 호출되어 HttpOnly cookie 를 부트스트랩한다.
|
|
334
339
|
*
|
package/dist/index.js
CHANGED
|
@@ -11778,6 +11778,7 @@ function fetchCredentialsForPath(url) {
|
|
|
11778
11778
|
return path.startsWith("/v1/public/") || path.startsWith("/v1/proxy/") ? "omit" : "include";
|
|
11779
11779
|
}
|
|
11780
11780
|
var TOKEN_STORAGE_KEY = "cb_auth_tokens";
|
|
11781
|
+
var NO_COOKIE_SESSION_COOLDOWN_MS = 6e4;
|
|
11781
11782
|
function gatewayCodeFromStatus(status) {
|
|
11782
11783
|
switch (status) {
|
|
11783
11784
|
case 502:
|
|
@@ -11922,6 +11923,7 @@ var HttpClient = class {
|
|
|
11922
11923
|
this.config.refreshToken = refreshToken;
|
|
11923
11924
|
this.persistTokens();
|
|
11924
11925
|
this.markSessionHint();
|
|
11926
|
+
this.clearNoCookieSessionMark();
|
|
11925
11927
|
}
|
|
11926
11928
|
clearTokens() {
|
|
11927
11929
|
this.config.accessToken = void 0;
|
|
@@ -11965,6 +11967,45 @@ var HttpClient = class {
|
|
|
11965
11967
|
return true;
|
|
11966
11968
|
}
|
|
11967
11969
|
}
|
|
11970
|
+
// ===== cookie 세션 없음 마커 (platform-issue 01a0237f) =====
|
|
11971
|
+
//
|
|
11972
|
+
// `refreshLockedUntil` 백오프는 인스턴스 안에서만 산다. 앱이 클라이언트를 새로 만들 때마다
|
|
11973
|
+
// 초기화되므로, 쿠키가 없는 브라우저에서는 인증 호출마다 re-issue 401 이 새로 나간다.
|
|
11974
|
+
// 이 마커는 같은 사실을 localStorage 에 짧게 남겨 인스턴스 경계를 넘어 공유한다.
|
|
11975
|
+
buildNoCookieSessionKey() {
|
|
11976
|
+
return `${this.storageKey}:no_cookie_session`;
|
|
11977
|
+
}
|
|
11978
|
+
markNoCookieSession() {
|
|
11979
|
+
if (typeof window === "undefined") return;
|
|
11980
|
+
try {
|
|
11981
|
+
localStorage.setItem(this.buildNoCookieSessionKey(), String(Date.now()));
|
|
11982
|
+
} catch {
|
|
11983
|
+
}
|
|
11984
|
+
}
|
|
11985
|
+
clearNoCookieSessionMark() {
|
|
11986
|
+
if (typeof window === "undefined") return;
|
|
11987
|
+
try {
|
|
11988
|
+
localStorage.removeItem(this.buildNoCookieSessionKey());
|
|
11989
|
+
} catch {
|
|
11990
|
+
}
|
|
11991
|
+
}
|
|
11992
|
+
/** 쿠키 전용 refresh 를 지금 건너뛰어야 하는지 (최근에 401/403 을 받았는지). */
|
|
11993
|
+
isNoCookieSessionMarkFresh() {
|
|
11994
|
+
if (typeof window === "undefined") return false;
|
|
11995
|
+
try {
|
|
11996
|
+
const raw = localStorage.getItem(this.buildNoCookieSessionKey());
|
|
11997
|
+
if (!raw) return false;
|
|
11998
|
+
const at = Number.parseInt(raw, 10);
|
|
11999
|
+
if (!Number.isFinite(at)) return false;
|
|
12000
|
+
if (Date.now() - at >= NO_COOKIE_SESSION_COOLDOWN_MS) {
|
|
12001
|
+
this.clearNoCookieSessionMark();
|
|
12002
|
+
return false;
|
|
12003
|
+
}
|
|
12004
|
+
return true;
|
|
12005
|
+
} catch {
|
|
12006
|
+
return false;
|
|
12007
|
+
}
|
|
12008
|
+
}
|
|
11968
12009
|
/**
|
|
11969
12010
|
* OAuth redirect callback 직후 호출되어 HttpOnly cookie 를 부트스트랩한다.
|
|
11970
12011
|
*
|
|
@@ -12150,6 +12191,11 @@ var HttpClient = class {
|
|
|
12150
12191
|
this.config.onAuthError?.(error);
|
|
12151
12192
|
throw error;
|
|
12152
12193
|
}
|
|
12194
|
+
if (!this.config.refreshToken && this.isNoCookieSessionMarkFresh()) {
|
|
12195
|
+
throw new AuthError(
|
|
12196
|
+
"No cookie session (recently rejected). Skipping token refresh."
|
|
12197
|
+
);
|
|
12198
|
+
}
|
|
12153
12199
|
this.isRefreshing = true;
|
|
12154
12200
|
if (!this.config.refreshToken && typeof window === "undefined") {
|
|
12155
12201
|
this.isRefreshing = false;
|
|
@@ -12241,6 +12287,7 @@ var HttpClient = class {
|
|
|
12241
12287
|
});
|
|
12242
12288
|
this.refreshFailureCount = 0;
|
|
12243
12289
|
this.refreshLockedUntil = 0;
|
|
12290
|
+
this.clearNoCookieSessionMark();
|
|
12244
12291
|
return data.access_token;
|
|
12245
12292
|
} catch (e) {
|
|
12246
12293
|
const baseMsg = e instanceof Error ? e.message : "Token refresh failed";
|
|
@@ -12250,6 +12297,9 @@ var HttpClient = class {
|
|
|
12250
12297
|
3e4
|
|
12251
12298
|
);
|
|
12252
12299
|
this.refreshLockedUntil = Date.now() + backoffMs;
|
|
12300
|
+
if (failureKind === "permanent" && !this.config.refreshToken) {
|
|
12301
|
+
this.markNoCookieSession();
|
|
12302
|
+
}
|
|
12253
12303
|
if (failureKind === "permanent") {
|
|
12254
12304
|
if (!silent) {
|
|
12255
12305
|
this.clearTokens();
|
package/dist/index.mjs
CHANGED
|
@@ -11729,6 +11729,7 @@ function fetchCredentialsForPath(url) {
|
|
|
11729
11729
|
return path.startsWith("/v1/public/") || path.startsWith("/v1/proxy/") ? "omit" : "include";
|
|
11730
11730
|
}
|
|
11731
11731
|
var TOKEN_STORAGE_KEY = "cb_auth_tokens";
|
|
11732
|
+
var NO_COOKIE_SESSION_COOLDOWN_MS = 6e4;
|
|
11732
11733
|
function gatewayCodeFromStatus(status) {
|
|
11733
11734
|
switch (status) {
|
|
11734
11735
|
case 502:
|
|
@@ -11873,6 +11874,7 @@ var HttpClient = class {
|
|
|
11873
11874
|
this.config.refreshToken = refreshToken;
|
|
11874
11875
|
this.persistTokens();
|
|
11875
11876
|
this.markSessionHint();
|
|
11877
|
+
this.clearNoCookieSessionMark();
|
|
11876
11878
|
}
|
|
11877
11879
|
clearTokens() {
|
|
11878
11880
|
this.config.accessToken = void 0;
|
|
@@ -11916,6 +11918,45 @@ var HttpClient = class {
|
|
|
11916
11918
|
return true;
|
|
11917
11919
|
}
|
|
11918
11920
|
}
|
|
11921
|
+
// ===== cookie 세션 없음 마커 (platform-issue 01a0237f) =====
|
|
11922
|
+
//
|
|
11923
|
+
// `refreshLockedUntil` 백오프는 인스턴스 안에서만 산다. 앱이 클라이언트를 새로 만들 때마다
|
|
11924
|
+
// 초기화되므로, 쿠키가 없는 브라우저에서는 인증 호출마다 re-issue 401 이 새로 나간다.
|
|
11925
|
+
// 이 마커는 같은 사실을 localStorage 에 짧게 남겨 인스턴스 경계를 넘어 공유한다.
|
|
11926
|
+
buildNoCookieSessionKey() {
|
|
11927
|
+
return `${this.storageKey}:no_cookie_session`;
|
|
11928
|
+
}
|
|
11929
|
+
markNoCookieSession() {
|
|
11930
|
+
if (typeof window === "undefined") return;
|
|
11931
|
+
try {
|
|
11932
|
+
localStorage.setItem(this.buildNoCookieSessionKey(), String(Date.now()));
|
|
11933
|
+
} catch {
|
|
11934
|
+
}
|
|
11935
|
+
}
|
|
11936
|
+
clearNoCookieSessionMark() {
|
|
11937
|
+
if (typeof window === "undefined") return;
|
|
11938
|
+
try {
|
|
11939
|
+
localStorage.removeItem(this.buildNoCookieSessionKey());
|
|
11940
|
+
} catch {
|
|
11941
|
+
}
|
|
11942
|
+
}
|
|
11943
|
+
/** 쿠키 전용 refresh 를 지금 건너뛰어야 하는지 (최근에 401/403 을 받았는지). */
|
|
11944
|
+
isNoCookieSessionMarkFresh() {
|
|
11945
|
+
if (typeof window === "undefined") return false;
|
|
11946
|
+
try {
|
|
11947
|
+
const raw = localStorage.getItem(this.buildNoCookieSessionKey());
|
|
11948
|
+
if (!raw) return false;
|
|
11949
|
+
const at = Number.parseInt(raw, 10);
|
|
11950
|
+
if (!Number.isFinite(at)) return false;
|
|
11951
|
+
if (Date.now() - at >= NO_COOKIE_SESSION_COOLDOWN_MS) {
|
|
11952
|
+
this.clearNoCookieSessionMark();
|
|
11953
|
+
return false;
|
|
11954
|
+
}
|
|
11955
|
+
return true;
|
|
11956
|
+
} catch {
|
|
11957
|
+
return false;
|
|
11958
|
+
}
|
|
11959
|
+
}
|
|
11919
11960
|
/**
|
|
11920
11961
|
* OAuth redirect callback 직후 호출되어 HttpOnly cookie 를 부트스트랩한다.
|
|
11921
11962
|
*
|
|
@@ -12101,6 +12142,11 @@ var HttpClient = class {
|
|
|
12101
12142
|
this.config.onAuthError?.(error);
|
|
12102
12143
|
throw error;
|
|
12103
12144
|
}
|
|
12145
|
+
if (!this.config.refreshToken && this.isNoCookieSessionMarkFresh()) {
|
|
12146
|
+
throw new AuthError(
|
|
12147
|
+
"No cookie session (recently rejected). Skipping token refresh."
|
|
12148
|
+
);
|
|
12149
|
+
}
|
|
12104
12150
|
this.isRefreshing = true;
|
|
12105
12151
|
if (!this.config.refreshToken && typeof window === "undefined") {
|
|
12106
12152
|
this.isRefreshing = false;
|
|
@@ -12192,6 +12238,7 @@ var HttpClient = class {
|
|
|
12192
12238
|
});
|
|
12193
12239
|
this.refreshFailureCount = 0;
|
|
12194
12240
|
this.refreshLockedUntil = 0;
|
|
12241
|
+
this.clearNoCookieSessionMark();
|
|
12195
12242
|
return data.access_token;
|
|
12196
12243
|
} catch (e) {
|
|
12197
12244
|
const baseMsg = e instanceof Error ? e.message : "Token refresh failed";
|
|
@@ -12201,6 +12248,9 @@ var HttpClient = class {
|
|
|
12201
12248
|
3e4
|
|
12202
12249
|
);
|
|
12203
12250
|
this.refreshLockedUntil = Date.now() + backoffMs;
|
|
12251
|
+
if (failureKind === "permanent" && !this.config.refreshToken) {
|
|
12252
|
+
this.markNoCookieSession();
|
|
12253
|
+
}
|
|
12204
12254
|
if (failureKind === "permanent") {
|
|
12205
12255
|
if (!silent) {
|
|
12206
12256
|
this.clearTokens();
|