@gh-platform/auth-sdk 1.0.2 → 1.0.3
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/README.md +1 -1
- package/dist/auth-sdk.es.js +8 -3
- package/dist/auth-sdk.min.js +1 -1
- package/dist/auth-sdk.umd.js +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/client.js +11 -7
- package/src/index.d.ts +1 -1
package/README.md
CHANGED
package/dist/auth-sdk.es.js
CHANGED
|
@@ -15,20 +15,22 @@ class AuthClient {
|
|
|
15
15
|
*/
|
|
16
16
|
constructor({
|
|
17
17
|
baseUrl,
|
|
18
|
+
introspectPath,
|
|
18
19
|
tenant = null,
|
|
19
20
|
loginPath = null,
|
|
20
21
|
refreshPath = null,
|
|
21
|
-
introspectPath = null,
|
|
22
22
|
headers = {},
|
|
23
23
|
storage = null
|
|
24
|
-
// <-- thêm storage vào constructor
|
|
25
24
|
}) {
|
|
26
25
|
if (!baseUrl) throw new Error("baseUrl is required");
|
|
27
26
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
27
|
+
if (!introspectUrl) {
|
|
28
|
+
throw new Error("introspectUrl is required");
|
|
29
|
+
}
|
|
28
30
|
const prefix = tenant ? `/api/v1/${tenant}/auth` : `/api/v1/auth`;
|
|
29
31
|
this.loginUrl = this.baseUrl + (loginPath || `${prefix}/login`);
|
|
30
32
|
this.refreshUrl = this.baseUrl + (refreshPath || `${prefix}/refresh`);
|
|
31
|
-
this.introspectUrl =
|
|
33
|
+
this.introspectUrl = introspectPath;
|
|
32
34
|
this.tenant = tenant;
|
|
33
35
|
this.headers = { "Content-Type": "application/json", ...headers };
|
|
34
36
|
this.storage = storage;
|
|
@@ -110,6 +112,9 @@ class AuthClient {
|
|
|
110
112
|
if (!finalToken) {
|
|
111
113
|
throw new Error("No access token available for introspection");
|
|
112
114
|
}
|
|
115
|
+
if (!this.introspectUrl) {
|
|
116
|
+
throw new Error("No introspect url config");
|
|
117
|
+
}
|
|
113
118
|
const headers = new Headers(this.headers);
|
|
114
119
|
headers.set("Authorization", `Bearer ${finalToken}`);
|
|
115
120
|
const res = await fetch(this.introspectUrl, {
|
package/dist/auth-sdk.min.js
CHANGED
|
@@ -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,
|
|
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,introspectPath:t,tenant:r=null,loginPath:s=null,refreshPath:o=null,headers:n={},storage:a=null}){if(!e)throw new Error("baseUrl is required");if(this.baseUrl=e.replace(/\/$/,""),!introspectUrl)throw new Error("introspectUrl is required");const i=r?`/api/v1/${r}/auth`:"/api/v1/auth";this.loginUrl=this.baseUrl+(s||`${i}/login`),this.refreshUrl=this.baseUrl+(o||`${i}/refresh`),this.introspectUrl=t,this.tenant=r,this.headers={"Content-Type":"application/json",...n},this.storage=a}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)}}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=new Headers(this.headers);r.set("Authorization",`Bearer ${t}`);const s=await fetch(this.introspectUrl,{method:"GET",headers:r});if(!s.ok){const e=await s.text().catch(()=>s.statusText);throw new Error(`Introspect failed: ${s.status} ${e}`)}let o;try{o=await s.json()}catch(e){throw console.error("❌ JSON parse error:",e),new Error("Invalid JSON response from server")}return o}}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=null){this.client=e,this.storage=t||new n("auth",e.tenant||null)}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)})}}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/auth-sdk.umd.js
CHANGED
|
@@ -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,
|
|
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,introspectPath:t,tenant:r=null,loginPath:s=null,refreshPath:o=null,headers:n={},storage:a=null}){if(!e)throw new Error("baseUrl is required");if(this.baseUrl=e.replace(/\/$/,""),!introspectUrl)throw new Error("introspectUrl is required");const i=r?`/api/v1/${r}/auth`:"/api/v1/auth";this.loginUrl=this.baseUrl+(s||`${i}/login`),this.refreshUrl=this.baseUrl+(o||`${i}/refresh`),this.introspectUrl=t,this.tenant=r,this.headers={"Content-Type":"application/json",...n},this.storage=a}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)}}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=new Headers(this.headers);r.set("Authorization",`Bearer ${t}`);const s=await fetch(this.introspectUrl,{method:"GET",headers:r});if(!s.ok){const e=await s.text().catch(()=>s.statusText);throw new Error(`Introspect failed: ${s.status} ${e}`)}let o;try{o=await s.json()}catch(n){throw console.error("❌ JSON parse error:",n),new Error("Invalid JSON response from server")}return o}}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=null){this.client=e,this.storage=t||new n("auth",e.tenant||null)}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)})}}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
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -11,26 +11,28 @@ export default class AuthClient {
|
|
|
11
11
|
*/
|
|
12
12
|
constructor({
|
|
13
13
|
baseUrl,
|
|
14
|
+
introspectPath,
|
|
14
15
|
tenant = null,
|
|
15
16
|
loginPath = null,
|
|
16
17
|
refreshPath = null,
|
|
17
|
-
introspectPath = null,
|
|
18
18
|
headers = {},
|
|
19
|
-
storage = null,
|
|
19
|
+
storage = null,
|
|
20
20
|
}) {
|
|
21
21
|
if (!baseUrl) throw new Error("baseUrl is required");
|
|
22
22
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
23
|
-
|
|
23
|
+
if (!introspectUrl) {
|
|
24
|
+
throw new Error("introspectUrl is required");
|
|
25
|
+
}
|
|
24
26
|
// default path builder: tenant-aware
|
|
25
27
|
const prefix = tenant ? `/api/v1/${tenant}/auth` : `/api/v1/auth`;
|
|
26
28
|
|
|
27
29
|
this.loginUrl = this.baseUrl + (loginPath || `${prefix}/login`);
|
|
28
30
|
this.refreshUrl = this.baseUrl + (refreshPath || `${prefix}/refresh`);
|
|
29
|
-
this.introspectUrl =
|
|
31
|
+
this.introspectUrl = introspectPath;
|
|
30
32
|
|
|
31
|
-
this.tenant = tenant;
|
|
33
|
+
this.tenant = tenant;
|
|
32
34
|
this.headers = { "Content-Type": "application/json", ...headers };
|
|
33
|
-
this.storage = storage;
|
|
35
|
+
this.storage = storage;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/**
|
|
@@ -130,7 +132,9 @@ export default class AuthClient {
|
|
|
130
132
|
if (!finalToken) {
|
|
131
133
|
throw new Error("No access token available for introspection");
|
|
132
134
|
}
|
|
133
|
-
|
|
135
|
+
if (!this.introspectUrl) {
|
|
136
|
+
throw new Error("No introspect url config");
|
|
137
|
+
}
|
|
134
138
|
const headers = new Headers(this.headers);
|
|
135
139
|
headers.set("Authorization", `Bearer ${finalToken}`);
|
|
136
140
|
const res = await fetch(this.introspectUrl, {
|
package/src/index.d.ts
CHANGED