@gh-platform/auth-sdk 1.0.12 → 1.0.14

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.
@@ -147,12 +147,10 @@ class AuthFetch {
147
147
  this.introspectUrl = `${introspectBaseUrl}/${introspectPath.replace(/^\//, "")}`;
148
148
  this.storage = storage || new TokenStorage("auth", authClient.tenant || null);
149
149
  }
150
- _setAuthCookie() {
151
- const maxAge = 60 * 5;
150
+ setAuthCookie() {
152
151
  const parts = [
153
152
  `auth_state=1`,
154
153
  `Path=/`,
155
- `Max-Age=${maxAge}`,
156
154
  `SameSite=Lax`
157
155
  ];
158
156
  if (location.protocol === "https:") {
@@ -160,7 +158,7 @@ class AuthFetch {
160
158
  }
161
159
  document.cookie = parts.join("; ");
162
160
  }
163
- _clearAuthCookie() {
161
+ clearAuthCookie() {
164
162
  document.cookie = `auth_state=; Path=/; Max-Age=0`;
165
163
  }
166
164
  /**
@@ -244,27 +242,14 @@ class AuthFetch {
244
242
  finalToken = this.storage.accessToken;
245
243
  }
246
244
  if (!finalToken) {
247
- this._clearAuthCookie();
248
245
  throw new Error("No access token available for introspection");
249
246
  }
250
247
  if (!this.introspectUrl) {
251
248
  throw new Error("No introspect url config");
252
249
  }
253
- let res;
254
- try {
255
- res = await this.fetch(this.introspectUrl, {
256
- method: "GET"
257
- });
258
- } catch (err) {
259
- throw err;
260
- }
261
- if (res.status === 401 || res.status === 403) {
262
- this._clearAuthCookie();
263
- throw new Error(`Unauthorized: ${res.status}`);
264
- }
265
- if (res.status >= 500) {
266
- throw new Error(`Auth service error: ${res.status}`);
267
- }
250
+ const res = await this.fetch(this.introspectUrl, {
251
+ method: "GET"
252
+ });
268
253
  if (!res.ok) {
269
254
  const text = await res.text().catch(() => res.statusText);
270
255
  throw new Error(`Introspect failed: ${res.status} ${text}`);
@@ -273,13 +258,9 @@ class AuthFetch {
273
258
  try {
274
259
  json = await res.json();
275
260
  } catch (e) {
276
- throw new Error("Invalid JSON response from auth service");
277
- }
278
- if (json.active === false) {
279
- this._clearAuthCookie();
280
- throw new Error("Token inactive");
261
+ console.error(" JSON parse error:", e);
262
+ throw new Error("Invalid JSON response from server");
281
263
  }
282
- this._setAuthCookie();
283
264
  return json;
284
265
  }
285
266
  }
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).AuthSDK={})}(this,function(e){"use strict";let t=null;function r(){return t}function s(e){t=e}class o{constructor({baseUrl:e,tenant:t=null,loginPath:r=null,refreshPath:s=null,headers:o={},storage:a=null}){if(!e)throw new Error("baseUrl is required");this.baseUrl=e.replace(/\/$/,"");const n=t?`/api/v1/${t}/auth`:"/api/v1/auth";this.loginUrl=this.baseUrl+(r||`${n}/login`),this.refreshUrl=this.baseUrl+(s||`${n}/refresh`),this.tenant=t,this.headers={"Content-Type":"application/json",...o},this.storage=a}async login(e,t,r=null,s={}){const o={identifier:e,password:t,...s};r&&(o.totp=r);const a=await fetch(this.loginUrl,{method:"POST",headers:this.headers,body:JSON.stringify(o)});if(!a.ok){const e=await a.text().catch(()=>a.statusText);throw new Error(`Login failed: ${a.status} ${e}`)}let n;try{n=await a.json()}catch(e){throw console.error("❌ JSON parse error:",e),new Error("Invalid JSON response from server")}const i=n.data||n;return this.storage&&(i.access_token&&(this.storage.accessToken=i.access_token),i.refresh_token&&(this.storage.refreshToken=i.refresh_token)),n}async refresh(e){if(r())return r();const t=(async()=>{const t=await fetch(this.refreshUrl,{method:"POST",headers:this.headers,body:JSON.stringify({refresh_token:e})});if(!t.ok){const e=await t.text().catch(()=>t.statusText);throw new Error(`Refresh failed: ${t.status} ${e}`)}let r;try{r=await t.json()}catch(e){throw console.error("❌ JSON parse error:",e),new Error("Invalid JSON response from server")}const s=r.data||r;return this.storage&&(s.access_token&&(this.storage.accessToken=s.access_token),s.refresh_token&&(this.storage.refreshToken=s.refresh_token)),r})();s(t);try{return await t}finally{s(null)}}}class a{constructor(e="auth",t=null){this.prefix=e,this.tenant=t}_key(e){return this.tenant?`${this.prefix}:${this.tenant}_${e}`:`${this.prefix}_${e}`}get accessToken(){return localStorage.getItem(this._key("access_token"))}set accessToken(e){null==e?localStorage.removeItem(this._key("access_token")):localStorage.setItem(this._key("access_token"),e)}get refreshToken(){return localStorage.getItem(this._key("refresh_token"))}set refreshToken(e){null==e?localStorage.removeItem(this._key("refresh_token")):localStorage.setItem(this._key("refresh_token"),e)}clear(){localStorage.removeItem(this._key("access_token")),localStorage.removeItem(this._key("refresh_token"))}}class n{constructor(e,t,r=null,s="introspect"){if(!t)throw new Error("introspectBaseUrl is required");this.client=e,this.introspectUrl=`${t}/${s.replace(/^\//,"")}`,this.storage=r||new a("auth",e.tenant||null)}_setAuthCookie(){const e=["auth_state=1","Path=/","Max-Age=300","SameSite=Lax"];"https:"===location.protocol&&e.push("Secure"),document.cookie=e.join("; ")}_clearAuthCookie(){document.cookie="auth_state=; Path=/; Max-Age=0"}async fetch(e,t={},r=null){const s=this.storage.accessToken,o=new Headers(t.headers||{});return s&&o.set("Authorization",`Bearer ${s}`),t.method&&"GET"!==t.method&&t.body?await this._xhrRequest(e,t,o,r):await this._fetchWithDownloadProgress(e,t,o,r)}async _fetchWithDownloadProgress(e,t,r,s){let o=await fetch(e,{...t,headers:r});if(401===o.status&&this.storage.refreshToken)try{const s=await this.client.refresh(this.storage.refreshToken);s.access_token&&(this.storage.accessToken=s.access_token),s.refresh_token&&(this.storage.refreshToken=s.refresh_token),r.set("Authorization",`Bearer ${this.storage.accessToken}`),o=await fetch(e,{...t,headers:r})}catch{throw this.storage.clear(),new Error("Unauthorized, please login again")}if(!s||!o.body)return o;const a=o.body.getReader(),n=+o.headers.get("Content-Length")||0;let i=0;const h=[];for(;;){const{done:e,value:t}=await a.read();if(e)break;h.push(t),i+=t.length,n?s(Math.round(i/n*100),i,n):s(null,i,null)}const c=new Blob(h);return new Response(c,o)}_xhrRequest(e,t,r,s){return new Promise((o,a)=>{const n=new XMLHttpRequest;n.open(t.method||"POST",e,!0);for(const[e,t]of r.entries())n.setRequestHeader(e,t);n.upload&&s&&(n.upload.onprogress=e=>{if(e.lengthComputable){const t=Math.round(e.loaded/e.total*100);s(t,e.loaded,e.total)}else s(null,e.loaded,null)}),n.onload=()=>{o(new Response(n.response,{status:n.status}))},n.onerror=()=>a(new Error("Network error")),n.send(t.body)})}async introspect(e=null){let t,r,s=e;if(this.storage&&!s&&(s=this.storage.accessToken),!s)throw this._clearAuthCookie(),new Error("No access token available for introspection");if(!this.introspectUrl)throw new Error("No introspect url config");try{t=await this.fetch(this.introspectUrl,{method:"GET"})}catch(e){throw e}if(401===t.status||403===t.status)throw this._clearAuthCookie(),new Error(`Unauthorized: ${t.status}`);if(t.status>=500)throw new Error(`Auth service error: ${t.status}`);if(!t.ok){const e=await t.text().catch(()=>t.statusText);throw new Error(`Introspect failed: ${t.status} ${e}`)}try{r=await t.json()}catch(e){throw new Error("Invalid JSON response from auth service")}if(!1===r.active)throw this._clearAuthCookie(),new Error("Token inactive");return this._setAuthCookie(),r}}const i={AuthClient:o,AuthFetch:n,TokenStorage:a};e.AuthClient=o,e.AuthFetch=n,e.TokenStorage=a,e.default=i,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).AuthSDK={})}(this,function(e){"use strict";let t=null;function r(){return t}function s(e){t=e}class o{constructor({baseUrl:e,tenant:t=null,loginPath:r=null,refreshPath:s=null,headers:o={},storage:n=null}){if(!e)throw new Error("baseUrl is required");this.baseUrl=e.replace(/\/$/,"");const a=t?`/api/v1/${t}/auth`:"/api/v1/auth";this.loginUrl=this.baseUrl+(r||`${a}/login`),this.refreshUrl=this.baseUrl+(s||`${a}/refresh`),this.tenant=t,this.headers={"Content-Type":"application/json",...o},this.storage=n}async login(e,t,r=null,s={}){const o={identifier:e,password:t,...s};r&&(o.totp=r);const n=await fetch(this.loginUrl,{method:"POST",headers:this.headers,body:JSON.stringify(o)});if(!n.ok){const e=await n.text().catch(()=>n.statusText);throw new Error(`Login failed: ${n.status} ${e}`)}let a;try{a=await n.json()}catch(e){throw console.error("❌ JSON parse error:",e),new Error("Invalid JSON response from server")}const i=a.data||a;return this.storage&&(i.access_token&&(this.storage.accessToken=i.access_token),i.refresh_token&&(this.storage.refreshToken=i.refresh_token)),a}async refresh(e){if(r())return r();const t=(async()=>{const t=await fetch(this.refreshUrl,{method:"POST",headers:this.headers,body:JSON.stringify({refresh_token:e})});if(!t.ok){const e=await t.text().catch(()=>t.statusText);throw new Error(`Refresh failed: ${t.status} ${e}`)}let r;try{r=await t.json()}catch(e){throw console.error("❌ JSON parse error:",e),new Error("Invalid JSON response from server")}const s=r.data||r;return this.storage&&(s.access_token&&(this.storage.accessToken=s.access_token),s.refresh_token&&(this.storage.refreshToken=s.refresh_token)),r})();s(t);try{return await t}finally{s(null)}}}class n{constructor(e="auth",t=null){this.prefix=e,this.tenant=t}_key(e){return this.tenant?`${this.prefix}:${this.tenant}_${e}`:`${this.prefix}_${e}`}get accessToken(){return localStorage.getItem(this._key("access_token"))}set accessToken(e){null==e?localStorage.removeItem(this._key("access_token")):localStorage.setItem(this._key("access_token"),e)}get refreshToken(){return localStorage.getItem(this._key("refresh_token"))}set refreshToken(e){null==e?localStorage.removeItem(this._key("refresh_token")):localStorage.setItem(this._key("refresh_token"),e)}clear(){localStorage.removeItem(this._key("access_token")),localStorage.removeItem(this._key("refresh_token"))}}class a{constructor(e,t,r=null,s="introspect"){if(!t)throw new Error("introspectBaseUrl is required");this.client=e,this.introspectUrl=`${t}/${s.replace(/^\//,"")}`,this.storage=r||new n("auth",e.tenant||null)}setAuthCookie(){const e=["auth_state=1","Path=/","SameSite=Lax"];"https:"===location.protocol&&e.push("Secure"),document.cookie=e.join("; ")}clearAuthCookie(){document.cookie="auth_state=; Path=/; Max-Age=0"}async fetch(e,t={},r=null){const s=this.storage.accessToken,o=new Headers(t.headers||{});return s&&o.set("Authorization",`Bearer ${s}`),t.method&&"GET"!==t.method&&t.body?await this._xhrRequest(e,t,o,r):await this._fetchWithDownloadProgress(e,t,o,r)}async _fetchWithDownloadProgress(e,t,r,s){let o=await fetch(e,{...t,headers:r});if(401===o.status&&this.storage.refreshToken)try{const s=await this.client.refresh(this.storage.refreshToken);s.access_token&&(this.storage.accessToken=s.access_token),s.refresh_token&&(this.storage.refreshToken=s.refresh_token),r.set("Authorization",`Bearer ${this.storage.accessToken}`),o=await fetch(e,{...t,headers:r})}catch{throw this.storage.clear(),new Error("Unauthorized, please login again")}if(!s||!o.body)return o;const n=o.body.getReader(),a=+o.headers.get("Content-Length")||0;let i=0;const h=[];for(;;){const{done:e,value:t}=await n.read();if(e)break;h.push(t),i+=t.length,a?s(Math.round(i/a*100),i,a):s(null,i,null)}const c=new Blob(h);return new Response(c,o)}_xhrRequest(e,t,r,s){return new Promise((o,n)=>{const a=new XMLHttpRequest;a.open(t.method||"POST",e,!0);for(const[e,t]of r.entries())a.setRequestHeader(e,t);a.upload&&s&&(a.upload.onprogress=e=>{if(e.lengthComputable){const t=Math.round(e.loaded/e.total*100);s(t,e.loaded,e.total)}else s(null,e.loaded,null)}),a.onload=()=>{o(new Response(a.response,{status:a.status}))},a.onerror=()=>n(new Error("Network error")),a.send(t.body)})}async introspect(e=null){let t=e;if(this.storage&&!t&&(t=this.storage.accessToken),!t)throw new Error("No access token available for introspection");if(!this.introspectUrl)throw new Error("No introspect url config");const r=await this.fetch(this.introspectUrl,{method:"GET"});if(!r.ok){const e=await r.text().catch(()=>r.statusText);throw new Error(`Introspect failed: ${r.status} ${e}`)}let s;try{s=await r.json()}catch(e){throw console.error(" JSON parse error:",e),new Error("Invalid JSON response from server")}return s}}const i={AuthClient:o,AuthFetch:a,TokenStorage:n};e.AuthClient=o,e.AuthFetch=a,e.TokenStorage=n,e.default=i,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).AuthSDK={})}(this,function(e){"use strict";let t=null;function r(){return t}function s(e){t=e}class o{constructor({baseUrl:e,tenant:t=null,loginPath:r=null,refreshPath:s=null,headers:o={},storage:a=null}){if(!e)throw new Error("baseUrl is required");this.baseUrl=e.replace(/\/$/,"");const n=t?`/api/v1/${t}/auth`:"/api/v1/auth";this.loginUrl=this.baseUrl+(r||`${n}/login`),this.refreshUrl=this.baseUrl+(s||`${n}/refresh`),this.tenant=t,this.headers={"Content-Type":"application/json",...o},this.storage=a}async login(e,t,r=null,s={}){const o={identifier:e,password:t,...s};r&&(o.totp=r);const a=await fetch(this.loginUrl,{method:"POST",headers:this.headers,body:JSON.stringify(o)});if(!a.ok){const e=await a.text().catch(()=>a.statusText);throw new Error(`Login failed: ${a.status} ${e}`)}let n;try{n=await a.json()}catch(h){throw console.error("❌ JSON parse error:",h),new Error("Invalid JSON response from server")}const i=n.data||n;return this.storage&&(i.access_token&&(this.storage.accessToken=i.access_token),i.refresh_token&&(this.storage.refreshToken=i.refresh_token)),n}async refresh(e){if(r())return r();const t=(async()=>{const t=await fetch(this.refreshUrl,{method:"POST",headers:this.headers,body:JSON.stringify({refresh_token:e})});if(!t.ok){const e=await t.text().catch(()=>t.statusText);throw new Error(`Refresh failed: ${t.status} ${e}`)}let r;try{r=await t.json()}catch(o){throw console.error("❌ JSON parse error:",o),new Error("Invalid JSON response from server")}const s=r.data||r;return this.storage&&(s.access_token&&(this.storage.accessToken=s.access_token),s.refresh_token&&(this.storage.refreshToken=s.refresh_token)),r})();s(t);try{return await t}finally{s(null)}}}class a{constructor(e="auth",t=null){this.prefix=e,this.tenant=t}_key(e){return this.tenant?`${this.prefix}:${this.tenant}_${e}`:`${this.prefix}_${e}`}get accessToken(){return localStorage.getItem(this._key("access_token"))}set accessToken(e){null==e?localStorage.removeItem(this._key("access_token")):localStorage.setItem(this._key("access_token"),e)}get refreshToken(){return localStorage.getItem(this._key("refresh_token"))}set refreshToken(e){null==e?localStorage.removeItem(this._key("refresh_token")):localStorage.setItem(this._key("refresh_token"),e)}clear(){localStorage.removeItem(this._key("access_token")),localStorage.removeItem(this._key("refresh_token"))}}class n{constructor(e,t,r=null,s="introspect"){if(!t)throw new Error("introspectBaseUrl is required");this.client=e,this.introspectUrl=`${t}/${s.replace(/^\//,"")}`,this.storage=r||new a("auth",e.tenant||null)}_setAuthCookie(){const e=["auth_state=1","Path=/","Max-Age=300","SameSite=Lax"];"https:"===location.protocol&&e.push("Secure"),document.cookie=e.join("; ")}_clearAuthCookie(){document.cookie="auth_state=; Path=/; Max-Age=0"}async fetch(e,t={},r=null){const s=this.storage.accessToken,o=new Headers(t.headers||{});return s&&o.set("Authorization",`Bearer ${s}`),t.method&&"GET"!==t.method&&t.body?await this._xhrRequest(e,t,o,r):await this._fetchWithDownloadProgress(e,t,o,r)}async _fetchWithDownloadProgress(e,t,r,s){let o=await fetch(e,{...t,headers:r});if(401===o.status&&this.storage.refreshToken)try{const s=await this.client.refresh(this.storage.refreshToken);s.access_token&&(this.storage.accessToken=s.access_token),s.refresh_token&&(this.storage.refreshToken=s.refresh_token),r.set("Authorization",`Bearer ${this.storage.accessToken}`),o=await fetch(e,{...t,headers:r})}catch{throw this.storage.clear(),new Error("Unauthorized, please login again")}if(!s||!o.body)return o;const a=o.body.getReader(),n=+o.headers.get("Content-Length")||0;let i=0;const h=[];for(;;){const{done:e,value:t}=await a.read();if(e)break;if(h.push(t),i+=t.length,n){s(Math.round(i/n*100),i,n)}else s(null,i,null)}const c=new Blob(h);return new Response(c,o)}_xhrRequest(e,t,r,s){return new Promise((o,a)=>{const n=new XMLHttpRequest;n.open(t.method||"POST",e,!0);for(const[e,t]of r.entries())n.setRequestHeader(e,t);n.upload&&s&&(n.upload.onprogress=e=>{if(e.lengthComputable){const t=Math.round(e.loaded/e.total*100);s(t,e.loaded,e.total)}else s(null,e.loaded,null)}),n.onload=()=>{o(new Response(n.response,{status:n.status}))},n.onerror=()=>a(new Error("Network error")),n.send(t.body)})}async introspect(e=null){let t,r,s=e;if(this.storage&&!s&&(s=this.storage.accessToken),!s)throw this._clearAuthCookie(),new Error("No access token available for introspection");if(!this.introspectUrl)throw new Error("No introspect url config");try{t=await this.fetch(this.introspectUrl,{method:"GET"})}catch(o){throw o}if(401===t.status||403===t.status)throw this._clearAuthCookie(),new Error(`Unauthorized: ${t.status}`);if(t.status>=500)throw new Error(`Auth service error: ${t.status}`);if(!t.ok){const e=await t.text().catch(()=>t.statusText);throw new Error(`Introspect failed: ${t.status} ${e}`)}try{r=await t.json()}catch(a){throw new Error("Invalid JSON response from auth service")}if(!1===r.active)throw this._clearAuthCookie(),new Error("Token inactive");return this._setAuthCookie(),r}}const i={AuthClient:o,AuthFetch:n,TokenStorage:a};e.AuthClient=o,e.AuthFetch=n,e.TokenStorage=a,e.default=i,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).AuthSDK={})}(this,function(e){"use strict";let t=null;function r(){return t}function s(e){t=e}class o{constructor({baseUrl:e,tenant:t=null,loginPath:r=null,refreshPath:s=null,headers:o={},storage:n=null}){if(!e)throw new Error("baseUrl is required");this.baseUrl=e.replace(/\/$/,"");const a=t?`/api/v1/${t}/auth`:"/api/v1/auth";this.loginUrl=this.baseUrl+(r||`${a}/login`),this.refreshUrl=this.baseUrl+(s||`${a}/refresh`),this.tenant=t,this.headers={"Content-Type":"application/json",...o},this.storage=n}async login(e,t,r=null,s={}){const o={identifier:e,password:t,...s};r&&(o.totp=r);const n=await fetch(this.loginUrl,{method:"POST",headers:this.headers,body:JSON.stringify(o)});if(!n.ok){const e=await n.text().catch(()=>n.statusText);throw new Error(`Login failed: ${n.status} ${e}`)}let a;try{a=await n.json()}catch(h){throw console.error("❌ JSON parse error:",h),new Error("Invalid JSON response from server")}const i=a.data||a;return this.storage&&(i.access_token&&(this.storage.accessToken=i.access_token),i.refresh_token&&(this.storage.refreshToken=i.refresh_token)),a}async refresh(e){if(r())return r();const t=(async()=>{const t=await fetch(this.refreshUrl,{method:"POST",headers:this.headers,body:JSON.stringify({refresh_token:e})});if(!t.ok){const e=await t.text().catch(()=>t.statusText);throw new Error(`Refresh failed: ${t.status} ${e}`)}let r;try{r=await t.json()}catch(o){throw console.error("❌ JSON parse error:",o),new Error("Invalid JSON response from server")}const s=r.data||r;return this.storage&&(s.access_token&&(this.storage.accessToken=s.access_token),s.refresh_token&&(this.storage.refreshToken=s.refresh_token)),r})();s(t);try{return await t}finally{s(null)}}}class n{constructor(e="auth",t=null){this.prefix=e,this.tenant=t}_key(e){return this.tenant?`${this.prefix}:${this.tenant}_${e}`:`${this.prefix}_${e}`}get accessToken(){return localStorage.getItem(this._key("access_token"))}set accessToken(e){null==e?localStorage.removeItem(this._key("access_token")):localStorage.setItem(this._key("access_token"),e)}get refreshToken(){return localStorage.getItem(this._key("refresh_token"))}set refreshToken(e){null==e?localStorage.removeItem(this._key("refresh_token")):localStorage.setItem(this._key("refresh_token"),e)}clear(){localStorage.removeItem(this._key("access_token")),localStorage.removeItem(this._key("refresh_token"))}}class a{constructor(e,t,r=null,s="introspect"){if(!t)throw new Error("introspectBaseUrl is required");this.client=e,this.introspectUrl=`${t}/${s.replace(/^\//,"")}`,this.storage=r||new n("auth",e.tenant||null)}setAuthCookie(){const e=["auth_state=1","Path=/","SameSite=Lax"];"https:"===location.protocol&&e.push("Secure"),document.cookie=e.join("; ")}clearAuthCookie(){document.cookie="auth_state=; Path=/; Max-Age=0"}async fetch(e,t={},r=null){const s=this.storage.accessToken,o=new Headers(t.headers||{});return s&&o.set("Authorization",`Bearer ${s}`),t.method&&"GET"!==t.method&&t.body?await this._xhrRequest(e,t,o,r):await this._fetchWithDownloadProgress(e,t,o,r)}async _fetchWithDownloadProgress(e,t,r,s){let o=await fetch(e,{...t,headers:r});if(401===o.status&&this.storage.refreshToken)try{const s=await this.client.refresh(this.storage.refreshToken);s.access_token&&(this.storage.accessToken=s.access_token),s.refresh_token&&(this.storage.refreshToken=s.refresh_token),r.set("Authorization",`Bearer ${this.storage.accessToken}`),o=await fetch(e,{...t,headers:r})}catch{throw this.storage.clear(),new Error("Unauthorized, please login again")}if(!s||!o.body)return o;const n=o.body.getReader(),a=+o.headers.get("Content-Length")||0;let i=0;const h=[];for(;;){const{done:e,value:t}=await n.read();if(e)break;if(h.push(t),i+=t.length,a){s(Math.round(i/a*100),i,a)}else s(null,i,null)}const c=new Blob(h);return new Response(c,o)}_xhrRequest(e,t,r,s){return new Promise((o,n)=>{const a=new XMLHttpRequest;a.open(t.method||"POST",e,!0);for(const[e,t]of r.entries())a.setRequestHeader(e,t);a.upload&&s&&(a.upload.onprogress=e=>{if(e.lengthComputable){const t=Math.round(e.loaded/e.total*100);s(t,e.loaded,e.total)}else s(null,e.loaded,null)}),a.onload=()=>{o(new Response(a.response,{status:a.status}))},a.onerror=()=>n(new Error("Network error")),a.send(t.body)})}async introspect(e=null){let t=e;if(this.storage&&!t&&(t=this.storage.accessToken),!t)throw new Error("No access token available for introspection");if(!this.introspectUrl)throw new Error("No introspect url config");const r=await this.fetch(this.introspectUrl,{method:"GET"});if(!r.ok){const e=await r.text().catch(()=>r.statusText);throw new Error(`Introspect failed: ${r.status} ${e}`)}let s;try{s=await r.json()}catch(o){throw console.error(" JSON parse error:",o),new Error("Invalid JSON response from server")}return s}}const i={AuthClient:o,AuthFetch:a,TokenStorage:n};e.AuthClient=o,e.AuthFetch=a,e.TokenStorage=n,e.default=i,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/dist/index.d.ts CHANGED
@@ -94,6 +94,8 @@ export class AuthFetch {
94
94
  onProgress?: ProgressCallback
95
95
  ): Promise<Response>;
96
96
  introspect(token?: string | null): Promise<AuthResponse>;
97
+ setAuthCookie();
98
+ clearAuthCookie();
97
99
  }
98
100
 
99
101
  declare const _default: {
package/package.json CHANGED
@@ -19,5 +19,5 @@
19
19
  },
20
20
  "type": "module",
21
21
  "types": "dist/index.d.ts",
22
- "version": "1.0.12"
23
- }
22
+ "version": "1.0.14"
23
+ }
package/src/index.d.ts CHANGED
@@ -94,6 +94,8 @@ export class AuthFetch {
94
94
  onProgress?: ProgressCallback
95
95
  ): Promise<Response>;
96
96
  introspect(token?: string | null): Promise<AuthResponse>;
97
+ setAuthCookie();
98
+ clearAuthCookie();
97
99
  }
98
100
 
99
101
  declare const _default: {
package/src/middleware.js CHANGED
@@ -10,14 +10,10 @@ export class AuthFetch {
10
10
  this.introspectUrl = (`${introspectBaseUrl}/${introspectPath.replace(/^\//, "")}`);
11
11
  this.storage = storage || new TokenStorage("auth", authClient.tenant || null);
12
12
  }
13
-
14
- _setAuthCookie() {
15
- const maxAge = 60 * 5; // 5 phút
16
-
13
+ setAuthCookie() {
17
14
  const parts = [
18
15
  `auth_state=1`,
19
16
  `Path=/`,
20
- `Max-Age=${maxAge}`,
21
17
  `SameSite=Lax`,
22
18
  ];
23
19
 
@@ -28,8 +24,7 @@ export class AuthFetch {
28
24
  document.cookie = parts.join("; ");
29
25
  }
30
26
 
31
-
32
- _clearAuthCookie() {
27
+ clearAuthCookie() {
33
28
  document.cookie = `auth_state=; Path=/; Max-Age=0`;
34
29
  }
35
30
 
@@ -141,44 +136,18 @@ export class AuthFetch {
141
136
  finalToken = this.storage.accessToken;
142
137
  }
143
138
 
144
- // ❌ không có token => chắc chắn chưa login
145
139
  if (!finalToken) {
146
- this._clearAuthCookie();
147
140
  throw new Error("No access token available for introspection");
148
141
  }
149
-
150
142
  if (!this.introspectUrl) {
151
143
  throw new Error("No introspect url config");
152
144
  }
153
145
 
154
- let res;
155
- try {
156
- res = await this.fetch(this.introspectUrl, {
157
- method: "GET",
158
- });
159
- } catch (err) {
160
- // ⚠️ NETWORK / FETCH ERROR
161
- // KHÔNG clear cookie
162
- throw err;
163
- }
164
-
165
- // ===============================
166
- // AUTH INVALID → CLEAR COOKIE
167
- // ===============================
168
- if (res.status === 401 || res.status === 403) {
169
- this._clearAuthCookie();
170
- throw new Error(`Unauthorized: ${res.status}`);
171
- }
172
-
173
- // ===============================
174
- // SERVER ERROR → KEEP COOKIE
175
- // ===============================
176
- if (res.status >= 500) {
177
- throw new Error(`Auth service error: ${res.status}`);
178
- }
146
+ const res = await this.fetch(this.introspectUrl, {
147
+ method: "GET",
148
+ });
179
149
 
180
150
  if (!res.ok) {
181
- // các status khác (400, 404...) → không clear
182
151
  const text = await res.text().catch(() => res.statusText);
183
152
  throw new Error(`Introspect failed: ${res.status} ${text}`);
184
153
  }
@@ -187,23 +156,10 @@ export class AuthFetch {
187
156
  try {
188
157
  json = await res.json();
189
158
  } catch (e) {
190
- // parse lỗi => system error
191
- throw new Error("Invalid JSON response from auth service");
159
+ console.error("❌ JSON parse error:", e);
160
+ throw new Error("Invalid JSON response from server");
192
161
  }
193
162
 
194
- // ===============================
195
- // AUTH SERVICE NÓI TOKEN INVALID
196
- // ===============================
197
- if (json.active === false) {
198
- this._clearAuthCookie();
199
- throw new Error("Token inactive");
200
- }
201
-
202
- // ===============================
203
- // AUTH OK → SET COOKIE
204
- // ===============================
205
- this._setAuthCookie();
206
-
207
163
  return json;
208
164
  }
209
165
  }