@roudanio/awesome-auth 0.1.3 → 0.1.4

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/dist/auth.d.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  import { default as EventEmitter3 } from 'eventemitter3';
2
2
  import { JwtPayload } from 'jwt-decode';
3
+ export type GoogleButtonOptions = {
4
+ type?: 'standard' | 'icon';
5
+ theme?: 'outline' | 'filled_blue' | 'filled_black';
6
+ size?: 'small' | 'medium' | 'large';
7
+ text?: 'signin_with' | 'signup_with' | 'continue_with' | 'signin';
8
+ shape?: 'rectangular' | 'pill' | 'circle' | 'square';
9
+ logo_alignment?: 'left' | 'center';
10
+ width?: number;
11
+ locale?: string;
12
+ };
3
13
  export interface AwesomeAuthProps {
4
14
  googleId: string;
5
15
  prefix?: string;
@@ -17,7 +27,7 @@ export declare enum AwesomeAuthEvent {
17
27
  }
18
28
  export declare class AwesomeAuth extends EventEmitter3 {
19
29
  #private;
20
- constructor({ googleId, prefix, root, }: AwesomeAuthProps);
30
+ constructor({ googleId, prefix, root }: AwesomeAuthProps);
21
31
  get accessToken(): string;
22
32
  get expiredIn(): number;
23
33
  get isVerifying(): boolean;
@@ -30,10 +40,14 @@ export declare class AwesomeAuth extends EventEmitter3 {
30
40
  store(key: string, value: unknown): Promise<void>;
31
41
  retrieve(key: string): Promise<unknown>;
32
42
  private initGoogleIdentity;
43
+ renderButton(target: HTMLElement, options?: GoogleButtonOptions): Promise<void>;
44
+ private ensureGoogleIdentityInitialized;
45
+ private handlePromptMoment;
33
46
  private refreshCountDown;
34
47
  private refreshToken;
35
48
  private setAccessToken;
36
49
  private verifyToken;
37
50
  private onGoogleIdentityCallback;
51
+ private getRevokeHint;
38
52
  }
39
53
  export declare function getInstance(params: AwesomeAuthProps): AwesomeAuth;
@@ -1 +1 @@
1
- var AwesomeAuth=(function(m){"use strict";function P(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var _={exports:{}},E;function G(){return E||(E=1,(function(e){var r=Object.prototype.hasOwnProperty,t="~";function a(){}Object.create&&(a.prototype=Object.create(null),new a().__proto__||(t=!1));function d(c,i,s){this.fn=c,this.context=i,this.once=s||!1}function v(c,i,s,o,p){if(typeof s!="function")throw new TypeError("The listener must be a function");var u=new d(s,o||c,p),l=t?t+i:i;return c._events[l]?c._events[l].fn?c._events[l]=[c._events[l],u]:c._events[l].push(u):(c._events[l]=u,c._eventsCount++),c}function I(c,i){--c._eventsCount===0?c._events=new a:delete c._events[i]}function h(){this._events=new a,this._eventsCount=0}h.prototype.eventNames=function(){var i=[],s,o;if(this._eventsCount===0)return i;for(o in s=this._events)r.call(s,o)&&i.push(t?o.slice(1):o);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(s)):i},h.prototype.listeners=function(i){var s=t?t+i:i,o=this._events[s];if(!o)return[];if(o.fn)return[o.fn];for(var p=0,u=o.length,l=new Array(u);p<u;p++)l[p]=o[p].fn;return l},h.prototype.listenerCount=function(i){var s=t?t+i:i,o=this._events[s];return o?o.fn?1:o.length:0},h.prototype.emit=function(i,s,o,p,u,l){var g=t?t+i:i;if(!this._events[g])return!1;var n=this._events[g],y=arguments.length,b,f;if(n.fn){switch(n.once&&this.removeListener(i,n.fn,void 0,!0),y){case 1:return n.fn.call(n.context),!0;case 2:return n.fn.call(n.context,s),!0;case 3:return n.fn.call(n.context,s,o),!0;case 4:return n.fn.call(n.context,s,o,p),!0;case 5:return n.fn.call(n.context,s,o,p,u),!0;case 6:return n.fn.call(n.context,s,o,p,u,l),!0}for(f=1,b=new Array(y-1);f<y;f++)b[f-1]=arguments[f];n.fn.apply(n.context,b)}else{var ie=n.length,T;for(f=0;f<ie;f++)switch(n[f].once&&this.removeListener(i,n[f].fn,void 0,!0),y){case 1:n[f].fn.call(n[f].context);break;case 2:n[f].fn.call(n[f].context,s);break;case 3:n[f].fn.call(n[f].context,s,o);break;case 4:n[f].fn.call(n[f].context,s,o,p);break;default:if(!b)for(T=1,b=new Array(y-1);T<y;T++)b[T-1]=arguments[T];n[f].fn.apply(n[f].context,b)}}return!0},h.prototype.on=function(i,s,o){return v(this,i,s,o,!1)},h.prototype.once=function(i,s,o){return v(this,i,s,o,!0)},h.prototype.removeListener=function(i,s,o,p){var u=t?t+i:i;if(!this._events[u])return this;if(!s)return I(this,u),this;var l=this._events[u];if(l.fn)l.fn===s&&(!p||l.once)&&(!o||l.context===o)&&I(this,u);else{for(var g=0,n=[],y=l.length;g<y;g++)(l[g].fn!==s||p&&!l[g].once||o&&l[g].context!==o)&&n.push(l[g]);n.length?this._events[u]=n.length===1?n[0]:n:I(this,u)}return this},h.prototype.removeAllListeners=function(i){var s;return i?(s=t?t+i:i,this._events[s]&&I(this,s)):(this._events=new a,this._eventsCount=0),this},h.prototype.off=h.prototype.removeListener,h.prototype.addListener=h.prototype.on,h.prefixed=t,h.EventEmitter=h,e.exports=h})(_)),_.exports}var L=G();const N=P(L);class w extends Error{}w.prototype.name="InvalidTokenError";function R(e){return decodeURIComponent(atob(e).replace(/(.)/g,(r,t)=>{let a=t.charCodeAt(0).toString(16).toUpperCase();return a.length<2&&(a="0"+a),"%"+a}))}function D(e){let r=e.replace(/-/g,"+").replace(/_/g,"/");switch(r.length%4){case 0:break;case 2:r+="==";break;case 3:r+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return R(r)}catch{return atob(r)}}function F(e,r){if(typeof e!="string")throw new w("Invalid token specified: must be a string");r||(r={});const t=r.header===!0?0:1,a=e.split(".")[t];if(typeof a!="string")throw new w(`Invalid token specified: missing part #${t+1}`);let d;try{d=D(a)}catch(v){throw new w(`Invalid token specified: invalid base64 for part #${t+1} (${v.message})`)}try{return JSON.parse(d)}catch(v){throw new w(`Invalid token specified: invalid json for part #${t+1} (${v.message})`)}}var V=typeof global=="object"&&global&&global.Object===Object&&global,z=typeof self=="object"&&self&&self.Object===Object&&self,J=V||z||Function("return this")(),O=J.Symbol,x=Object.prototype,U=x.hasOwnProperty,B=x.toString,S=O?O.toStringTag:void 0;function q(e){var r=U.call(e,S),t=e[S];try{e[S]=void 0;var a=!0}catch{}var d=B.call(e);return a&&(r?e[S]=t:delete e[S]),d}var K=Object.prototype,M=K.toString;function H(e){return M.call(e)}var Y="[object Null]",Q="[object Undefined]",C=O?O.toStringTag:void 0;function W(e){return e==null?e===void 0?Q:Y:C&&C in Object(e)?q(e):H(e)}var X=Array.isArray;function Z(e){return e!=null&&typeof e=="object"}var ee="[object String]";function te(e){return typeof e=="string"||!X(e)&&Z(e)&&W(e)==ee}var $=(e=>(e.INIT="init",e.VERIFYING="verifying",e.VERIFIED="verified",e.REFRESH="refresh",e.ERROR="error",e))($||{});let j;class A extends N{#e="";#t={};#s=0;#c;#o=!1;#n=!1;#i=!1;#a;#l;#r;constructor({googleId:r,prefix:t="aAuth",root:a="/api"}){if(super(),this.#c=r,this.#l=t,this.#r=a,this.#a=Date.now()/1e3>>0,this.setAccessToken(localStorage.getItem(this.localKey)||"",!1),this.#e){this.verifyToken().then(d=>{d||this.initGoogleIdentity()});return}this.initGoogleIdentity()}get accessToken(){return this.#e}get expiredIn(){return this.#s?0:this.#s-this.#a}get isVerifying(){return this.#n}get isVerified(){return this.#i}get localKey(){return`${this.#l}-token`}get root(){return this.#r}get user(){return this.#t}doSignIn(){this.initGoogleIdentity()}doSignOut(){this.#e="",google.accounts.id.revoke(this.#t.sub||""),this.#t={}}async store(r,t){t=te(t)?t:JSON.stringify(t),await fetch(`${this.#r}/store`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#e}`},body:JSON.stringify({key:r,value:t})})}async retrieve(r){const t=await fetch(`${this.#r}/retrieve`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#e}`},body:JSON.stringify({key:r})}),{data:a}=await t.json();return a?.value}initGoogleIdentity(){if(!("google"in globalThis)||!("accounts"in globalThis.google)){re(),globalThis.onGoogleLibraryLoad=()=>this.initGoogleIdentity();return}this.#o||(this.emit("init",!0),this.#o=!0,google.accounts.id.initialize({client_id:this.#c,callback:r=>this.onGoogleIdentityCallback(r),auto_select:!0,ux_mode:"popup"}),google.accounts.id.prompt())}refreshCountDown(){this.#a=Date.now()/1e3>>0,this.expiredIn<=60&&(clearInterval(j),this.refreshToken())}async refreshToken(){this.emit("refresh",!0);const r=await fetch(`${this.#r}/refresh-token`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#e}`}}),{data:t}=await r.json(),{token:a}=t;this.setAccessToken(a),this.emit("refresh",!1)}setAccessToken(r,t=!0){if(this.#e=r,t&&localStorage.setItem(this.localKey,r),!r){this.#t={},this.#s=0;return}try{this.#t=F(r)}catch{this.#t={}}this.#s=this.#t.exp||0,this.expiredIn>0&&(clearInterval(j),j=setInterval(()=>this.refreshCountDown(),1e3))}async verifyToken(){this.emit("verifying",!0),this.#n=!0;try{const r=await fetch(`${this.#r}/verify-auth`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#e}`}}),{data:t}=await r.json();t&&(this.#t=t,this.#i=!0,this.emit("verified",!0))}catch(r){this.#i=!1,this.emit("error",r.message||String(r))}return this.emit("verifying",!1),this.#n=!1,this.#i}async onGoogleIdentityCallback(r){this.emit("init",!1),this.#o=!1,this.emit("verifying",!0),this.#n=!0;const t=await fetch(`${this.#r}/google-auth`,{method:"POST",headers:{"Content-type":"application/json"},body:JSON.stringify({credential:r.credential})}),{data:a}=await t.json();a||this.emit("error","Failed to validate user.");const{token:d}=a;this.setAccessToken(d),this.emit("verifying",!1),this.#n=!1,this.emit("verified",!0),this.#i=!0}}function re(){const e="https://accounts.google.com/gsi/client";if(document.querySelector(`script[src="${e}"]`))return;const r=document.createElement("script");r.src=e,r.async=!0,document.head.appendChild(r)}let k;function ne(e){return k=k||new A(e),k}return m.AwesomeAuth=A,m.AwesomeAuthEvent=$,m.getInstance=ne,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"}),m})({});
1
+ var AwesomeAuth=(function(I){"use strict";function L(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}var k={exports:{}},C;function R(){return C||(C=1,(function(r){var e=Object.prototype.hasOwnProperty,t="~";function a(){}Object.create&&(a.prototype=Object.create(null),new a().__proto__||(t=!1));function f(c,i,s){this.fn=c,this.context=i,this.once=s||!1}function p(c,i,s,o,g){if(typeof s!="function")throw new TypeError("The listener must be a function");var d=new f(s,o||c,g),l=t?t+i:i;return c._events[l]?c._events[l].fn?c._events[l]=[c._events[l],d]:c._events[l].push(d):(c._events[l]=d,c._eventsCount++),c}function w(c,i){--c._eventsCount===0?c._events=new a:delete c._events[i]}function u(){this._events=new a,this._eventsCount=0}u.prototype.eventNames=function(){var i=[],s,o;if(this._eventsCount===0)return i;for(o in s=this._events)e.call(s,o)&&i.push(t?o.slice(1):o);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(s)):i},u.prototype.listeners=function(i){var s=t?t+i:i,o=this._events[s];if(!o)return[];if(o.fn)return[o.fn];for(var g=0,d=o.length,l=new Array(d);g<d;g++)l[g]=o[g].fn;return l},u.prototype.listenerCount=function(i){var s=t?t+i:i,o=this._events[s];return o?o.fn?1:o.length:0},u.prototype.emit=function(i,s,o,g,d,l){var y=t?t+i:i;if(!this._events[y])return!1;var n=this._events[y],v=arguments.length,m,h;if(n.fn){switch(n.once&&this.removeListener(i,n.fn,void 0,!0),v){case 1:return n.fn.call(n.context),!0;case 2:return n.fn.call(n.context,s),!0;case 3:return n.fn.call(n.context,s,o),!0;case 4:return n.fn.call(n.context,s,o,g),!0;case 5:return n.fn.call(n.context,s,o,g,d),!0;case 6:return n.fn.call(n.context,s,o,g,d,l),!0}for(h=1,m=new Array(v-1);h<v;h++)m[h-1]=arguments[h];n.fn.apply(n.context,m)}else{var oe=n.length,O;for(h=0;h<oe;h++)switch(n[h].once&&this.removeListener(i,n[h].fn,void 0,!0),v){case 1:n[h].fn.call(n[h].context);break;case 2:n[h].fn.call(n[h].context,s);break;case 3:n[h].fn.call(n[h].context,s,o);break;case 4:n[h].fn.call(n[h].context,s,o,g);break;default:if(!m)for(O=1,m=new Array(v-1);O<v;O++)m[O-1]=arguments[O];n[h].fn.apply(n[h].context,m)}}return!0},u.prototype.on=function(i,s,o){return p(this,i,s,o,!1)},u.prototype.once=function(i,s,o){return p(this,i,s,o,!0)},u.prototype.removeListener=function(i,s,o,g){var d=t?t+i:i;if(!this._events[d])return this;if(!s)return w(this,d),this;var l=this._events[d];if(l.fn)l.fn===s&&(!g||l.once)&&(!o||l.context===o)&&w(this,d);else{for(var y=0,n=[],v=l.length;y<v;y++)(l[y].fn!==s||g&&!l[y].once||o&&l[y].context!==o)&&n.push(l[y]);n.length?this._events[d]=n.length===1?n[0]:n:w(this,d)}return this},u.prototype.removeAllListeners=function(i){var s;return i?(s=t?t+i:i,this._events[s]&&w(this,s)):(this._events=new a,this._eventsCount=0),this},u.prototype.off=u.prototype.removeListener,u.prototype.addListener=u.prototype.on,u.prefixed=t,u.EventEmitter=u,r.exports=u})(k)),k.exports}var D=R();const N=L(D);class S extends Error{}S.prototype.name="InvalidTokenError";function z(r){return decodeURIComponent(atob(r).replace(/(.)/g,(e,t)=>{let a=t.charCodeAt(0).toString(16).toUpperCase();return a.length<2&&(a="0"+a),"%"+a}))}function B(r){let e=r.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return z(e)}catch{return atob(e)}}function F(r,e){if(typeof r!="string")throw new S("Invalid token specified: must be a string");e||(e={});const t=e.header===!0?0:1,a=r.split(".")[t];if(typeof a!="string")throw new S(`Invalid token specified: missing part #${t+1}`);let f;try{f=B(a)}catch(p){throw new S(`Invalid token specified: invalid base64 for part #${t+1} (${p.message})`)}try{return JSON.parse(f)}catch(p){throw new S(`Invalid token specified: invalid json for part #${t+1} (${p.message})`)}}var M=typeof global=="object"&&global&&global.Object===Object&&global,V=typeof self=="object"&&self&&self.Object===Object&&self,J=M||V||Function("return this")(),_=J.Symbol,$=Object.prototype,U=$.hasOwnProperty,q=$.toString,T=_?_.toStringTag:void 0;function H(r){var e=U.call(r,T),t=r[T];try{r[T]=void 0;var a=!0}catch{}var f=q.call(r);return a&&(e?r[T]=t:delete r[T]),f}var K=Object.prototype,Y=K.toString;function Q(r){return Y.call(r)}var W="[object Null]",X="[object Undefined]",A=_?_.toStringTag:void 0;function Z(r){return r==null?r===void 0?X:W:A&&A in Object(r)?H(r):Q(r)}var ee=Array.isArray;function te(r){return r!=null&&typeof r=="object"}var re="[object String]";function ne(r){return typeof r=="string"||!ee(r)&&te(r)&&Z(r)==re}var P=(r=>(r.INIT="init",r.VERIFYING="verifying",r.VERIFIED="verified",r.REFRESH="refresh",r.ERROR="error",r))(P||{});let j;class G extends N{#t="";#e={};#o=0;#c;#i=!1;#s=!1;#n=!1;#l=!1;#a;#h;#r;constructor({googleId:e,prefix:t="aAuth",root:a="/api"}){if(super(),this.#c=e,this.#h=t,this.#r=a,this.#a=Date.now()/1e3>>0,this.setAccessToken(localStorage.getItem(this.localKey)||"",!1),this.#t){this.verifyToken().then(f=>{f||this.initGoogleIdentity()});return}this.initGoogleIdentity()}get accessToken(){return this.#t}get expiredIn(){return this.#o?0:this.#o-this.#a}get isVerifying(){return this.#s}get isVerified(){return this.#n}get localKey(){return`${this.#h}-token`}get root(){return this.#r}get user(){return this.#e}doSignIn(){this.initGoogleIdentity()}doSignOut(){const e=this.getRevokeHint();this.setAccessToken(""),this.#e={},this.#n=!1,clearInterval(j),this.emit("verified",!1),e&&"google"in globalThis&&"accounts"in globalThis.google&&google.accounts.id.revoke(e)}async store(e,t){t=ne(t)?t:JSON.stringify(t),await fetch(`${this.#r}/store`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#t}`},body:JSON.stringify({key:e,value:t})})}async retrieve(e){const t=await fetch(`${this.#r}/retrieve`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#t}`},body:JSON.stringify({key:e})}),{data:a}=await t.json();return a?.value}initGoogleIdentity(){this.#i||(this.emit("init",!0),this.#i=!0,this.ensureGoogleIdentityInitialized().then(()=>{google.accounts.id.prompt(e=>{this.handlePromptMoment(e)})}).catch(e=>{this.#i=!1,this.emit("init",!1),this.emit("error",e.message||String(e))}))}async renderButton(e,t){if(e){try{await this.ensureGoogleIdentityInitialized()}catch(a){this.emit("error",a.message||String(a));return}if(!E()){this.emit("error","Google Identity Services 未加载完成");return}google.accounts.id.renderButton(e,{type:"standard",theme:"outline",size:"large",text:"signin_with",...t})}}async ensureGoogleIdentityInitialized(){if(await ie(),!E())throw new Error("Google Identity Services 未加载完成");this.#l||(google.accounts.id.initialize({client_id:this.#c,callback:e=>this.onGoogleIdentityCallback(e),auto_select:!0,ux_mode:"popup"}),this.#l=!0)}handlePromptMoment(e){(e.isNotDisplayed()||e.isSkippedMoment()||e.isDismissedMoment())&&(this.#i=!1,this.emit("init",!1))}refreshCountDown(){this.#a=Date.now()/1e3>>0,this.expiredIn<=60&&(clearInterval(j),this.refreshToken())}async refreshToken(){this.emit("refresh",!0);const e=await fetch(`${this.#r}/refresh-token`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#t}`}}),{data:t}=await e.json(),{token:a}=t;this.setAccessToken(a),this.emit("refresh",!1)}setAccessToken(e,t=!0){if(this.#t=e,t&&localStorage.setItem(this.localKey,e),!e){this.#e={},this.#o=0;return}try{this.#e=F(e)}catch{this.#e={}}this.#o=this.#e.exp||0,this.expiredIn>0&&(clearInterval(j),j=setInterval(()=>this.refreshCountDown(),1e3))}async verifyToken(){this.emit("verifying",!0),this.#s=!0;try{const e=await fetch(`${this.#r}/verify-auth`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#t}`}}),{data:t}=await e.json();t&&(this.#e=t,this.#n=!0,this.emit("verified",!0))}catch(e){this.#n=!1,this.emit("error",e.message||String(e))}return this.emit("verifying",!1),this.#s=!1,this.#n}async onGoogleIdentityCallback(e){this.emit("init",!1),this.#i=!1,this.emit("verifying",!0),this.#s=!0;const t=await fetch(`${this.#r}/google-auth`,{method:"POST",headers:{"Content-type":"application/json"},body:JSON.stringify({credential:e.credential})}),{data:a}=await t.json();a||this.emit("error","Failed to validate user.");const{token:f}=a;this.setAccessToken(f),this.emit("verifying",!1),this.#s=!1,this.emit("verified",!0),this.#n=!0}getRevokeHint(){const e=this.#e.email;if(typeof e=="string"&&e.trim())return e;const t=this.#e.sub;return typeof t=="string"&&t.trim()?t:""}}let b=null;function E(){return"google"in globalThis&&"accounts"in globalThis.google}function ie(){return E()?Promise.resolve():b||(b=new Promise((r,e)=>{const t="https://accounts.google.com/gsi/client",a=document.querySelector(`script[src="${t}"]`),f=a||document.createElement("script");function p(){r()}function w(){e(new Error("Google Identity Services 加载失败"))}f.addEventListener("load",p,{once:!0}),f.addEventListener("error",w,{once:!0}),a||(f.src=t,f.async=!0,document.head.appendChild(f))}),b.catch(()=>{b=null}),b)}let x;function se(r){return x=x||new G(r),x}return I.AwesomeAuth=G,I.AwesomeAuthEvent=P,I.getInstance=se,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"}),I})({});
@@ -1,50 +1,50 @@
1
- function $(e) {
2
- return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
1
+ function G(r) {
2
+ return r && r.__esModule && Object.prototype.hasOwnProperty.call(r, "default") ? r.default : r;
3
3
  }
4
- var _ = { exports: {} }, k;
5
- function P() {
6
- return k || (k = 1, (function(e) {
7
- var r = Object.prototype.hasOwnProperty, t = "~";
4
+ var j = { exports: {} }, E;
5
+ function A() {
6
+ return E || (E = 1, (function(r) {
7
+ var e = Object.prototype.hasOwnProperty, t = "~";
8
8
  function a() {
9
9
  }
10
10
  Object.create && (a.prototype = /* @__PURE__ */ Object.create(null), new a().__proto__ || (t = !1));
11
- function d(c, i, s) {
11
+ function f(c, i, s) {
12
12
  this.fn = c, this.context = i, this.once = s || !1;
13
13
  }
14
- function v(c, i, s, o, p) {
14
+ function p(c, i, s, o, g) {
15
15
  if (typeof s != "function")
16
16
  throw new TypeError("The listener must be a function");
17
- var u = new d(s, o || c, p), l = t ? t + i : i;
18
- return c._events[l] ? c._events[l].fn ? c._events[l] = [c._events[l], u] : c._events[l].push(u) : (c._events[l] = u, c._eventsCount++), c;
17
+ var d = new f(s, o || c, g), l = t ? t + i : i;
18
+ return c._events[l] ? c._events[l].fn ? c._events[l] = [c._events[l], d] : c._events[l].push(d) : (c._events[l] = d, c._eventsCount++), c;
19
19
  }
20
- function S(c, i) {
20
+ function b(c, i) {
21
21
  --c._eventsCount === 0 ? c._events = new a() : delete c._events[i];
22
22
  }
23
- function h() {
23
+ function u() {
24
24
  this._events = new a(), this._eventsCount = 0;
25
25
  }
26
- h.prototype.eventNames = function() {
26
+ u.prototype.eventNames = function() {
27
27
  var i = [], s, o;
28
28
  if (this._eventsCount === 0) return i;
29
29
  for (o in s = this._events)
30
- r.call(s, o) && i.push(t ? o.slice(1) : o);
30
+ e.call(s, o) && i.push(t ? o.slice(1) : o);
31
31
  return Object.getOwnPropertySymbols ? i.concat(Object.getOwnPropertySymbols(s)) : i;
32
- }, h.prototype.listeners = function(i) {
32
+ }, u.prototype.listeners = function(i) {
33
33
  var s = t ? t + i : i, o = this._events[s];
34
34
  if (!o) return [];
35
35
  if (o.fn) return [o.fn];
36
- for (var p = 0, u = o.length, l = new Array(u); p < u; p++)
37
- l[p] = o[p].fn;
36
+ for (var g = 0, d = o.length, l = new Array(d); g < d; g++)
37
+ l[g] = o[g].fn;
38
38
  return l;
39
- }, h.prototype.listenerCount = function(i) {
39
+ }, u.prototype.listenerCount = function(i) {
40
40
  var s = t ? t + i : i, o = this._events[s];
41
41
  return o ? o.fn ? 1 : o.length : 0;
42
- }, h.prototype.emit = function(i, s, o, p, u, l) {
43
- var g = t ? t + i : i;
44
- if (!this._events[g]) return !1;
45
- var n = this._events[g], y = arguments.length, b, f;
42
+ }, u.prototype.emit = function(i, s, o, g, d, l) {
43
+ var y = t ? t + i : i;
44
+ if (!this._events[y]) return !1;
45
+ var n = this._events[y], v = arguments.length, m, h;
46
46
  if (n.fn) {
47
- switch (n.once && this.removeListener(i, n.fn, void 0, !0), y) {
47
+ switch (n.once && this.removeListener(i, n.fn, void 0, !0), v) {
48
48
  case 1:
49
49
  return n.fn.call(n.context), !0;
50
50
  case 2:
@@ -52,301 +52,347 @@ function P() {
52
52
  case 3:
53
53
  return n.fn.call(n.context, s, o), !0;
54
54
  case 4:
55
- return n.fn.call(n.context, s, o, p), !0;
55
+ return n.fn.call(n.context, s, o, g), !0;
56
56
  case 5:
57
- return n.fn.call(n.context, s, o, p, u), !0;
57
+ return n.fn.call(n.context, s, o, g, d), !0;
58
58
  case 6:
59
- return n.fn.call(n.context, s, o, p, u, l), !0;
59
+ return n.fn.call(n.context, s, o, g, d, l), !0;
60
60
  }
61
- for (f = 1, b = new Array(y - 1); f < y; f++)
62
- b[f - 1] = arguments[f];
63
- n.fn.apply(n.context, b);
61
+ for (h = 1, m = new Array(v - 1); h < v; h++)
62
+ m[h - 1] = arguments[h];
63
+ n.fn.apply(n.context, m);
64
64
  } else {
65
- var C = n.length, m;
66
- for (f = 0; f < C; f++)
67
- switch (n[f].once && this.removeListener(i, n[f].fn, void 0, !0), y) {
65
+ var P = n.length, I;
66
+ for (h = 0; h < P; h++)
67
+ switch (n[h].once && this.removeListener(i, n[h].fn, void 0, !0), v) {
68
68
  case 1:
69
- n[f].fn.call(n[f].context);
69
+ n[h].fn.call(n[h].context);
70
70
  break;
71
71
  case 2:
72
- n[f].fn.call(n[f].context, s);
72
+ n[h].fn.call(n[h].context, s);
73
73
  break;
74
74
  case 3:
75
- n[f].fn.call(n[f].context, s, o);
75
+ n[h].fn.call(n[h].context, s, o);
76
76
  break;
77
77
  case 4:
78
- n[f].fn.call(n[f].context, s, o, p);
78
+ n[h].fn.call(n[h].context, s, o, g);
79
79
  break;
80
80
  default:
81
- if (!b) for (m = 1, b = new Array(y - 1); m < y; m++)
82
- b[m - 1] = arguments[m];
83
- n[f].fn.apply(n[f].context, b);
81
+ if (!m) for (I = 1, m = new Array(v - 1); I < v; I++)
82
+ m[I - 1] = arguments[I];
83
+ n[h].fn.apply(n[h].context, m);
84
84
  }
85
85
  }
86
86
  return !0;
87
- }, h.prototype.on = function(i, s, o) {
88
- return v(this, i, s, o, !1);
89
- }, h.prototype.once = function(i, s, o) {
90
- return v(this, i, s, o, !0);
91
- }, h.prototype.removeListener = function(i, s, o, p) {
92
- var u = t ? t + i : i;
93
- if (!this._events[u]) return this;
87
+ }, u.prototype.on = function(i, s, o) {
88
+ return p(this, i, s, o, !1);
89
+ }, u.prototype.once = function(i, s, o) {
90
+ return p(this, i, s, o, !0);
91
+ }, u.prototype.removeListener = function(i, s, o, g) {
92
+ var d = t ? t + i : i;
93
+ if (!this._events[d]) return this;
94
94
  if (!s)
95
- return S(this, u), this;
96
- var l = this._events[u];
95
+ return b(this, d), this;
96
+ var l = this._events[d];
97
97
  if (l.fn)
98
- l.fn === s && (!p || l.once) && (!o || l.context === o) && S(this, u);
98
+ l.fn === s && (!g || l.once) && (!o || l.context === o) && b(this, d);
99
99
  else {
100
- for (var g = 0, n = [], y = l.length; g < y; g++)
101
- (l[g].fn !== s || p && !l[g].once || o && l[g].context !== o) && n.push(l[g]);
102
- n.length ? this._events[u] = n.length === 1 ? n[0] : n : S(this, u);
100
+ for (var y = 0, n = [], v = l.length; y < v; y++)
101
+ (l[y].fn !== s || g && !l[y].once || o && l[y].context !== o) && n.push(l[y]);
102
+ n.length ? this._events[d] = n.length === 1 ? n[0] : n : b(this, d);
103
103
  }
104
104
  return this;
105
- }, h.prototype.removeAllListeners = function(i) {
105
+ }, u.prototype.removeAllListeners = function(i) {
106
106
  var s;
107
- return i ? (s = t ? t + i : i, this._events[s] && S(this, s)) : (this._events = new a(), this._eventsCount = 0), this;
108
- }, h.prototype.off = h.prototype.removeListener, h.prototype.addListener = h.prototype.on, h.prefixed = t, h.EventEmitter = h, e.exports = h;
109
- })(_)), _.exports;
107
+ return i ? (s = t ? t + i : i, this._events[s] && b(this, s)) : (this._events = new a(), this._eventsCount = 0), this;
108
+ }, u.prototype.off = u.prototype.removeListener, u.prototype.addListener = u.prototype.on, u.prefixed = t, u.EventEmitter = u, r.exports = u;
109
+ })(j)), j.exports;
110
110
  }
111
- var A = P();
112
- const G = /* @__PURE__ */ $(A);
111
+ var L = A();
112
+ const R = /* @__PURE__ */ G(L);
113
113
  class T extends Error {
114
114
  }
115
115
  T.prototype.name = "InvalidTokenError";
116
- function L(e) {
117
- return decodeURIComponent(atob(e).replace(/(.)/g, (r, t) => {
116
+ function D(r) {
117
+ return decodeURIComponent(atob(r).replace(/(.)/g, (e, t) => {
118
118
  let a = t.charCodeAt(0).toString(16).toUpperCase();
119
119
  return a.length < 2 && (a = "0" + a), "%" + a;
120
120
  }));
121
121
  }
122
- function N(e) {
123
- let r = e.replace(/-/g, "+").replace(/_/g, "/");
124
- switch (r.length % 4) {
122
+ function N(r) {
123
+ let e = r.replace(/-/g, "+").replace(/_/g, "/");
124
+ switch (e.length % 4) {
125
125
  case 0:
126
126
  break;
127
127
  case 2:
128
- r += "==";
128
+ e += "==";
129
129
  break;
130
130
  case 3:
131
- r += "=";
131
+ e += "=";
132
132
  break;
133
133
  default:
134
134
  throw new Error("base64 string is not of the correct length");
135
135
  }
136
136
  try {
137
- return L(r);
137
+ return D(e);
138
138
  } catch {
139
- return atob(r);
139
+ return atob(e);
140
140
  }
141
141
  }
142
- function R(e, r) {
143
- if (typeof e != "string")
142
+ function z(r, e) {
143
+ if (typeof r != "string")
144
144
  throw new T("Invalid token specified: must be a string");
145
- r || (r = {});
146
- const t = r.header === !0 ? 0 : 1, a = e.split(".")[t];
145
+ e || (e = {});
146
+ const t = e.header === !0 ? 0 : 1, a = r.split(".")[t];
147
147
  if (typeof a != "string")
148
148
  throw new T(`Invalid token specified: missing part #${t + 1}`);
149
- let d;
149
+ let f;
150
150
  try {
151
- d = N(a);
152
- } catch (v) {
153
- throw new T(`Invalid token specified: invalid base64 for part #${t + 1} (${v.message})`);
151
+ f = N(a);
152
+ } catch (p) {
153
+ throw new T(`Invalid token specified: invalid base64 for part #${t + 1} (${p.message})`);
154
154
  }
155
155
  try {
156
- return JSON.parse(d);
157
- } catch (v) {
158
- throw new T(`Invalid token specified: invalid json for part #${t + 1} (${v.message})`);
156
+ return JSON.parse(f);
157
+ } catch (p) {
158
+ throw new T(`Invalid token specified: invalid json for part #${t + 1} (${p.message})`);
159
159
  }
160
160
  }
161
- var D = typeof global == "object" && global && global.Object === Object && global, F = typeof self == "object" && self && self.Object === Object && self, V = D || F || Function("return this")(), O = V.Symbol, E = Object.prototype, z = E.hasOwnProperty, J = E.toString, w = O ? O.toStringTag : void 0;
162
- function U(e) {
163
- var r = z.call(e, w), t = e[w];
161
+ var B = typeof global == "object" && global && global.Object === Object && global, F = typeof self == "object" && self && self.Object === Object && self, V = B || F || Function("return this")(), O = V.Symbol, $ = Object.prototype, J = $.hasOwnProperty, M = $.toString, S = O ? O.toStringTag : void 0;
162
+ function U(r) {
163
+ var e = J.call(r, S), t = r[S];
164
164
  try {
165
- e[w] = void 0;
165
+ r[S] = void 0;
166
166
  var a = !0;
167
167
  } catch {
168
168
  }
169
- var d = J.call(e);
170
- return a && (r ? e[w] = t : delete e[w]), d;
169
+ var f = M.call(r);
170
+ return a && (e ? r[S] = t : delete r[S]), f;
171
171
  }
172
- var B = Object.prototype, q = B.toString;
173
- function K(e) {
174
- return q.call(e);
172
+ var q = Object.prototype, H = q.toString;
173
+ function K(r) {
174
+ return H.call(r);
175
175
  }
176
- var H = "[object Null]", M = "[object Undefined]", x = O ? O.toStringTag : void 0;
177
- function Y(e) {
178
- return e == null ? e === void 0 ? M : H : x && x in Object(e) ? U(e) : K(e);
176
+ var Y = "[object Null]", Q = "[object Undefined]", C = O ? O.toStringTag : void 0;
177
+ function W(r) {
178
+ return r == null ? r === void 0 ? Q : Y : C && C in Object(r) ? U(r) : K(r);
179
179
  }
180
- var Q = Array.isArray;
181
- function W(e) {
182
- return e != null && typeof e == "object";
180
+ var X = Array.isArray;
181
+ function Z(r) {
182
+ return r != null && typeof r == "object";
183
183
  }
184
- var X = "[object String]";
185
- function Z(e) {
186
- return typeof e == "string" || !Q(e) && W(e) && Y(e) == X;
184
+ var ee = "[object String]";
185
+ function te(r) {
186
+ return typeof r == "string" || !X(r) && Z(r) && W(r) == ee;
187
187
  }
188
- var ee = /* @__PURE__ */ ((e) => (e.INIT = "init", e.VERIFYING = "verifying", e.VERIFIED = "verified", e.REFRESH = "refresh", e.ERROR = "error", e))(ee || {});
189
- let I;
190
- class te extends G {
191
- #e = "";
192
- #t = {};
193
- #s = 0;
188
+ var re = /* @__PURE__ */ ((r) => (r.INIT = "init", r.VERIFYING = "verifying", r.VERIFIED = "verified", r.REFRESH = "refresh", r.ERROR = "error", r))(re || {});
189
+ let _;
190
+ class ne extends R {
191
+ #t = "";
192
+ #e = {};
193
+ #o = 0;
194
194
  #c;
195
- #o = !1;
196
- #n = !1;
197
195
  #i = !1;
196
+ #s = !1;
197
+ #n = !1;
198
+ #l = !1;
198
199
  #a;
199
- #l;
200
+ #h;
200
201
  #r;
201
- constructor({
202
- googleId: r,
203
- prefix: t = "aAuth",
204
- root: a = "/api"
205
- }) {
206
- if (super(), this.#c = r, this.#l = t, this.#r = a, this.#a = Date.now() / 1e3 >> 0, this.setAccessToken(localStorage.getItem(this.localKey) || "", !1), this.#e) {
207
- this.verifyToken().then((d) => {
208
- d || this.initGoogleIdentity();
202
+ constructor({ googleId: e, prefix: t = "aAuth", root: a = "/api" }) {
203
+ if (super(), this.#c = e, this.#h = t, this.#r = a, this.#a = Date.now() / 1e3 >> 0, this.setAccessToken(localStorage.getItem(this.localKey) || "", !1), this.#t) {
204
+ this.verifyToken().then((f) => {
205
+ f || this.initGoogleIdentity();
209
206
  });
210
207
  return;
211
208
  }
212
209
  this.initGoogleIdentity();
213
210
  }
214
211
  get accessToken() {
215
- return this.#e;
212
+ return this.#t;
216
213
  }
217
214
  get expiredIn() {
218
- return this.#s ? 0 : this.#s - this.#a;
215
+ return this.#o ? 0 : this.#o - this.#a;
219
216
  }
220
217
  get isVerifying() {
221
- return this.#n;
218
+ return this.#s;
222
219
  }
223
220
  get isVerified() {
224
- return this.#i;
221
+ return this.#n;
225
222
  }
226
223
  get localKey() {
227
- return `${this.#l}-token`;
224
+ return `${this.#h}-token`;
228
225
  }
229
226
  get root() {
230
227
  return this.#r;
231
228
  }
232
229
  get user() {
233
- return this.#t;
230
+ return this.#e;
234
231
  }
235
232
  doSignIn() {
236
233
  this.initGoogleIdentity();
237
234
  }
238
235
  doSignOut() {
239
- this.#e = "", google.accounts.id.revoke(this.#t.sub || ""), this.#t = {};
236
+ const e = this.getRevokeHint();
237
+ this.setAccessToken(""), this.#e = {}, this.#n = !1, clearInterval(_), this.emit("verified", !1), e && "google" in globalThis && "accounts" in globalThis.google && google.accounts.id.revoke(e);
240
238
  }
241
- async store(r, t) {
242
- t = Z(t) ? t : JSON.stringify(t), await fetch(`${this.#r}/store`, {
239
+ async store(e, t) {
240
+ t = te(t) ? t : JSON.stringify(t), await fetch(`${this.#r}/store`, {
243
241
  method: "POST",
244
242
  headers: {
245
243
  "Content-type": "application/json",
246
- Authorization: `Bearer ${this.#e}`
244
+ Authorization: `Bearer ${this.#t}`
247
245
  },
248
246
  body: JSON.stringify({
249
- key: r,
247
+ key: e,
250
248
  value: t
251
249
  })
252
250
  });
253
251
  }
254
- async retrieve(r) {
252
+ async retrieve(e) {
255
253
  const t = await fetch(`${this.#r}/retrieve`, {
256
254
  method: "POST",
257
255
  headers: {
258
256
  "Content-type": "application/json",
259
- Authorization: `Bearer ${this.#e}`
257
+ Authorization: `Bearer ${this.#t}`
260
258
  },
261
259
  body: JSON.stringify({
262
- key: r
260
+ key: e
263
261
  })
264
262
  }), { data: a } = await t.json();
265
263
  return a?.value;
266
264
  }
267
265
  initGoogleIdentity() {
268
- if (!("google" in globalThis) || !("accounts" in globalThis.google)) {
269
- re(), globalThis.onGoogleLibraryLoad = () => this.initGoogleIdentity();
270
- return;
266
+ this.#i || (this.emit("init", !0), this.#i = !0, this.ensureGoogleIdentityInitialized().then(() => {
267
+ google.accounts.id.prompt((e) => {
268
+ this.handlePromptMoment(e);
269
+ });
270
+ }).catch((e) => {
271
+ this.#i = !1, this.emit("init", !1), this.emit("error", e.message || String(e));
272
+ }));
273
+ }
274
+ async renderButton(e, t) {
275
+ if (e) {
276
+ try {
277
+ await this.ensureGoogleIdentityInitialized();
278
+ } catch (a) {
279
+ this.emit("error", a.message || String(a));
280
+ return;
281
+ }
282
+ if (!x()) {
283
+ this.emit("error", "Google Identity Services 未加载完成");
284
+ return;
285
+ }
286
+ google.accounts.id.renderButton(e, {
287
+ type: "standard",
288
+ theme: "outline",
289
+ size: "large",
290
+ text: "signin_with",
291
+ ...t
292
+ });
271
293
  }
272
- this.#o || (this.emit("init", !0), this.#o = !0, google.accounts.id.initialize({
294
+ }
295
+ async ensureGoogleIdentityInitialized() {
296
+ if (await ie(), !x())
297
+ throw new Error("Google Identity Services 未加载完成");
298
+ this.#l || (google.accounts.id.initialize({
273
299
  client_id: this.#c,
274
- callback: (r) => this.onGoogleIdentityCallback(r),
300
+ callback: (e) => this.onGoogleIdentityCallback(e),
275
301
  auto_select: !0,
276
302
  ux_mode: "popup"
277
- }), google.accounts.id.prompt());
303
+ }), this.#l = !0);
304
+ }
305
+ handlePromptMoment(e) {
306
+ (e.isNotDisplayed() || e.isSkippedMoment() || e.isDismissedMoment()) && (this.#i = !1, this.emit("init", !1));
278
307
  }
279
308
  refreshCountDown() {
280
- this.#a = Date.now() / 1e3 >> 0, this.expiredIn <= 60 && (clearInterval(I), this.refreshToken());
309
+ this.#a = Date.now() / 1e3 >> 0, this.expiredIn <= 60 && (clearInterval(_), this.refreshToken());
281
310
  }
282
311
  async refreshToken() {
283
312
  this.emit("refresh", !0);
284
- const r = await fetch(`${this.#r}/refresh-token`, {
313
+ const e = await fetch(`${this.#r}/refresh-token`, {
285
314
  method: "POST",
286
315
  headers: {
287
316
  "Content-type": "application/json",
288
- Authorization: `Bearer ${this.#e}`
317
+ Authorization: `Bearer ${this.#t}`
289
318
  }
290
- }), { data: t } = await r.json(), { token: a } = t;
319
+ }), { data: t } = await e.json(), { token: a } = t;
291
320
  this.setAccessToken(a), this.emit("refresh", !1);
292
321
  }
293
- setAccessToken(r, t = !0) {
294
- if (this.#e = r, t && localStorage.setItem(this.localKey, r), !r) {
295
- this.#t = {}, this.#s = 0;
322
+ setAccessToken(e, t = !0) {
323
+ if (this.#t = e, t && localStorage.setItem(this.localKey, e), !e) {
324
+ this.#e = {}, this.#o = 0;
296
325
  return;
297
326
  }
298
327
  try {
299
- this.#t = R(r);
328
+ this.#e = z(e);
300
329
  } catch {
301
- this.#t = {};
330
+ this.#e = {};
302
331
  }
303
- this.#s = this.#t.exp || 0, this.expiredIn > 0 && (clearInterval(I), I = setInterval(() => this.refreshCountDown(), 1e3));
332
+ this.#o = this.#e.exp || 0, this.expiredIn > 0 && (clearInterval(_), _ = setInterval(() => this.refreshCountDown(), 1e3));
304
333
  }
305
334
  async verifyToken() {
306
- this.emit("verifying", !0), this.#n = !0;
335
+ this.emit("verifying", !0), this.#s = !0;
307
336
  try {
308
- const r = await fetch(`${this.#r}/verify-auth`, {
337
+ const e = await fetch(`${this.#r}/verify-auth`, {
309
338
  method: "POST",
310
339
  headers: {
311
340
  "Content-type": "application/json",
312
- Authorization: `Bearer ${this.#e}`
341
+ Authorization: `Bearer ${this.#t}`
313
342
  }
314
- }), { data: t } = await r.json();
315
- t && (this.#t = t, this.#i = !0, this.emit("verified", !0));
316
- } catch (r) {
317
- this.#i = !1, this.emit("error", r.message || String(r));
343
+ }), { data: t } = await e.json();
344
+ t && (this.#e = t, this.#n = !0, this.emit("verified", !0));
345
+ } catch (e) {
346
+ this.#n = !1, this.emit("error", e.message || String(e));
318
347
  }
319
- return this.emit("verifying", !1), this.#n = !1, this.#i;
348
+ return this.emit("verifying", !1), this.#s = !1, this.#n;
320
349
  }
321
- async onGoogleIdentityCallback(r) {
322
- this.emit("init", !1), this.#o = !1, this.emit("verifying", !0), this.#n = !0;
350
+ async onGoogleIdentityCallback(e) {
351
+ this.emit("init", !1), this.#i = !1, this.emit("verifying", !0), this.#s = !0;
323
352
  const t = await fetch(`${this.#r}/google-auth`, {
324
353
  method: "POST",
325
354
  headers: {
326
355
  "Content-type": "application/json"
327
356
  },
328
357
  body: JSON.stringify({
329
- credential: r.credential
358
+ credential: e.credential
330
359
  })
331
360
  }), { data: a } = await t.json();
332
361
  a || this.emit("error", "Failed to validate user.");
333
- const { token: d } = a;
334
- this.setAccessToken(d), this.emit("verifying", !1), this.#n = !1, this.emit("verified", !0), this.#i = !0;
362
+ const { token: f } = a;
363
+ this.setAccessToken(f), this.emit("verifying", !1), this.#s = !1, this.emit("verified", !0), this.#n = !0;
364
+ }
365
+ getRevokeHint() {
366
+ const e = this.#e.email;
367
+ if (typeof e == "string" && e.trim()) return e;
368
+ const t = this.#e.sub;
369
+ return typeof t == "string" && t.trim() ? t : "";
335
370
  }
336
371
  }
337
- function re() {
338
- const e = "https://accounts.google.com/gsi/client";
339
- if (document.querySelector(`script[src="${e}"]`))
340
- return;
341
- const r = document.createElement("script");
342
- r.src = e, r.async = !0, document.head.appendChild(r);
372
+ let w = null;
373
+ function x() {
374
+ return "google" in globalThis && "accounts" in globalThis.google;
375
+ }
376
+ function ie() {
377
+ return x() ? Promise.resolve() : w || (w = new Promise((r, e) => {
378
+ const t = "https://accounts.google.com/gsi/client", a = document.querySelector(`script[src="${t}"]`), f = a || document.createElement("script");
379
+ function p() {
380
+ r();
381
+ }
382
+ function b() {
383
+ e(new Error("Google Identity Services 加载失败"));
384
+ }
385
+ f.addEventListener("load", p, { once: !0 }), f.addEventListener("error", b, { once: !0 }), a || (f.src = t, f.async = !0, document.head.appendChild(f));
386
+ }), w.catch(() => {
387
+ w = null;
388
+ }), w);
343
389
  }
344
- let j;
345
- function ne(e) {
346
- return j = j || new te(e), j;
390
+ let k;
391
+ function se(r) {
392
+ return k = k || new ne(r), k;
347
393
  }
348
394
  export {
349
- te as AwesomeAuth,
350
- ee as AwesomeAuthEvent,
351
- ne as getInstance
395
+ ne as AwesomeAuth,
396
+ re as AwesomeAuthEvent,
397
+ se as getInstance
352
398
  };
@@ -1 +1 @@
1
- (function(y,w){typeof exports=="object"&&typeof module<"u"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(y=typeof globalThis<"u"?globalThis:y||self,w(y.AwesomeAuth={}))})(this,(function(y){"use strict";function w(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var _={exports:{}},E;function G(){return E||(E=1,(function(e){var n=Object.prototype.hasOwnProperty,t="~";function a(){}Object.create&&(a.prototype=Object.create(null),new a().__proto__||(t=!1));function p(c,i,s){this.fn=c,this.context=i,this.once=s||!1}function b(c,i,s,o,d){if(typeof s!="function")throw new TypeError("The listener must be a function");var u=new p(s,o||c,d),f=t?t+i:i;return c._events[f]?c._events[f].fn?c._events[f]=[c._events[f],u]:c._events[f].push(u):(c._events[f]=u,c._eventsCount++),c}function I(c,i){--c._eventsCount===0?c._events=new a:delete c._events[i]}function h(){this._events=new a,this._eventsCount=0}h.prototype.eventNames=function(){var i=[],s,o;if(this._eventsCount===0)return i;for(o in s=this._events)n.call(s,o)&&i.push(t?o.slice(1):o);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(s)):i},h.prototype.listeners=function(i){var s=t?t+i:i,o=this._events[s];if(!o)return[];if(o.fn)return[o.fn];for(var d=0,u=o.length,f=new Array(u);d<u;d++)f[d]=o[d].fn;return f},h.prototype.listenerCount=function(i){var s=t?t+i:i,o=this._events[s];return o?o.fn?1:o.length:0},h.prototype.emit=function(i,s,o,d,u,f){var g=t?t+i:i;if(!this._events[g])return!1;var r=this._events[g],v=arguments.length,m,l;if(r.fn){switch(r.once&&this.removeListener(i,r.fn,void 0,!0),v){case 1:return r.fn.call(r.context),!0;case 2:return r.fn.call(r.context,s),!0;case 3:return r.fn.call(r.context,s,o),!0;case 4:return r.fn.call(r.context,s,o,d),!0;case 5:return r.fn.call(r.context,s,o,d,u),!0;case 6:return r.fn.call(r.context,s,o,d,u,f),!0}for(l=1,m=new Array(v-1);l<v;l++)m[l-1]=arguments[l];r.fn.apply(r.context,m)}else{var ie=r.length,O;for(l=0;l<ie;l++)switch(r[l].once&&this.removeListener(i,r[l].fn,void 0,!0),v){case 1:r[l].fn.call(r[l].context);break;case 2:r[l].fn.call(r[l].context,s);break;case 3:r[l].fn.call(r[l].context,s,o);break;case 4:r[l].fn.call(r[l].context,s,o,d);break;default:if(!m)for(O=1,m=new Array(v-1);O<v;O++)m[O-1]=arguments[O];r[l].fn.apply(r[l].context,m)}}return!0},h.prototype.on=function(i,s,o){return b(this,i,s,o,!1)},h.prototype.once=function(i,s,o){return b(this,i,s,o,!0)},h.prototype.removeListener=function(i,s,o,d){var u=t?t+i:i;if(!this._events[u])return this;if(!s)return I(this,u),this;var f=this._events[u];if(f.fn)f.fn===s&&(!d||f.once)&&(!o||f.context===o)&&I(this,u);else{for(var g=0,r=[],v=f.length;g<v;g++)(f[g].fn!==s||d&&!f[g].once||o&&f[g].context!==o)&&r.push(f[g]);r.length?this._events[u]=r.length===1?r[0]:r:I(this,u)}return this},h.prototype.removeAllListeners=function(i){var s;return i?(s=t?t+i:i,this._events[s]&&I(this,s)):(this._events=new a,this._eventsCount=0),this},h.prototype.off=h.prototype.removeListener,h.prototype.addListener=h.prototype.on,h.prefixed=t,h.EventEmitter=h,e.exports=h})(_)),_.exports}var L=G();const N=w(L);class T extends Error{}T.prototype.name="InvalidTokenError";function R(e){return decodeURIComponent(atob(e).replace(/(.)/g,(n,t)=>{let a=t.charCodeAt(0).toString(16).toUpperCase();return a.length<2&&(a="0"+a),"%"+a}))}function D(e){let n=e.replace(/-/g,"+").replace(/_/g,"/");switch(n.length%4){case 0:break;case 2:n+="==";break;case 3:n+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return R(n)}catch{return atob(n)}}function F(e,n){if(typeof e!="string")throw new T("Invalid token specified: must be a string");n||(n={});const t=n.header===!0?0:1,a=e.split(".")[t];if(typeof a!="string")throw new T(`Invalid token specified: missing part #${t+1}`);let p;try{p=D(a)}catch(b){throw new T(`Invalid token specified: invalid base64 for part #${t+1} (${b.message})`)}try{return JSON.parse(p)}catch(b){throw new T(`Invalid token specified: invalid json for part #${t+1} (${b.message})`)}}var V=typeof global=="object"&&global&&global.Object===Object&&global,z=typeof self=="object"&&self&&self.Object===Object&&self,J=V||z||Function("return this")(),j=J.Symbol,C=Object.prototype,U=C.hasOwnProperty,B=C.toString,S=j?j.toStringTag:void 0;function q(e){var n=U.call(e,S),t=e[S];try{e[S]=void 0;var a=!0}catch{}var p=B.call(e);return a&&(n?e[S]=t:delete e[S]),p}var K=Object.prototype,M=K.toString;function H(e){return M.call(e)}var Y="[object Null]",Q="[object Undefined]",$=j?j.toStringTag:void 0;function W(e){return e==null?e===void 0?Q:Y:$&&$ in Object(e)?q(e):H(e)}var X=Array.isArray;function Z(e){return e!=null&&typeof e=="object"}var ee="[object String]";function te(e){return typeof e=="string"||!X(e)&&Z(e)&&W(e)==ee}var A=(e=>(e.INIT="init",e.VERIFYING="verifying",e.VERIFIED="verified",e.REFRESH="refresh",e.ERROR="error",e))(A||{});let k;class P extends N{#e="";#t={};#s=0;#c;#o=!1;#r=!1;#i=!1;#a;#f;#n;constructor({googleId:n,prefix:t="aAuth",root:a="/api"}){if(super(),this.#c=n,this.#f=t,this.#n=a,this.#a=Date.now()/1e3>>0,this.setAccessToken(localStorage.getItem(this.localKey)||"",!1),this.#e){this.verifyToken().then(p=>{p||this.initGoogleIdentity()});return}this.initGoogleIdentity()}get accessToken(){return this.#e}get expiredIn(){return this.#s?0:this.#s-this.#a}get isVerifying(){return this.#r}get isVerified(){return this.#i}get localKey(){return`${this.#f}-token`}get root(){return this.#n}get user(){return this.#t}doSignIn(){this.initGoogleIdentity()}doSignOut(){this.#e="",google.accounts.id.revoke(this.#t.sub||""),this.#t={}}async store(n,t){t=te(t)?t:JSON.stringify(t),await fetch(`${this.#n}/store`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#e}`},body:JSON.stringify({key:n,value:t})})}async retrieve(n){const t=await fetch(`${this.#n}/retrieve`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#e}`},body:JSON.stringify({key:n})}),{data:a}=await t.json();return a?.value}initGoogleIdentity(){if(!("google"in globalThis)||!("accounts"in globalThis.google)){ne(),globalThis.onGoogleLibraryLoad=()=>this.initGoogleIdentity();return}this.#o||(this.emit("init",!0),this.#o=!0,google.accounts.id.initialize({client_id:this.#c,callback:n=>this.onGoogleIdentityCallback(n),auto_select:!0,ux_mode:"popup"}),google.accounts.id.prompt())}refreshCountDown(){this.#a=Date.now()/1e3>>0,this.expiredIn<=60&&(clearInterval(k),this.refreshToken())}async refreshToken(){this.emit("refresh",!0);const n=await fetch(`${this.#n}/refresh-token`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#e}`}}),{data:t}=await n.json(),{token:a}=t;this.setAccessToken(a),this.emit("refresh",!1)}setAccessToken(n,t=!0){if(this.#e=n,t&&localStorage.setItem(this.localKey,n),!n){this.#t={},this.#s=0;return}try{this.#t=F(n)}catch{this.#t={}}this.#s=this.#t.exp||0,this.expiredIn>0&&(clearInterval(k),k=setInterval(()=>this.refreshCountDown(),1e3))}async verifyToken(){this.emit("verifying",!0),this.#r=!0;try{const n=await fetch(`${this.#n}/verify-auth`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#e}`}}),{data:t}=await n.json();t&&(this.#t=t,this.#i=!0,this.emit("verified",!0))}catch(n){this.#i=!1,this.emit("error",n.message||String(n))}return this.emit("verifying",!1),this.#r=!1,this.#i}async onGoogleIdentityCallback(n){this.emit("init",!1),this.#o=!1,this.emit("verifying",!0),this.#r=!0;const t=await fetch(`${this.#n}/google-auth`,{method:"POST",headers:{"Content-type":"application/json"},body:JSON.stringify({credential:n.credential})}),{data:a}=await t.json();a||this.emit("error","Failed to validate user.");const{token:p}=a;this.setAccessToken(p),this.emit("verifying",!1),this.#r=!1,this.emit("verified",!0),this.#i=!0}}function ne(){const e="https://accounts.google.com/gsi/client";if(document.querySelector(`script[src="${e}"]`))return;const n=document.createElement("script");n.src=e,n.async=!0,document.head.appendChild(n)}let x;function re(e){return x=x||new P(e),x}y.AwesomeAuth=P,y.AwesomeAuthEvent=A,y.getInstance=re,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(v,S){typeof exports=="object"&&typeof module<"u"?S(exports):typeof define=="function"&&define.amd?define(["exports"],S):(v=typeof globalThis<"u"?globalThis:v||self,S(v.AwesomeAuth={}))})(this,(function(v){"use strict";function S(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var E={exports:{}},$;function R(){return $||($=1,(function(n){var e=Object.prototype.hasOwnProperty,t="~";function a(){}Object.create&&(a.prototype=Object.create(null),new a().__proto__||(t=!1));function h(c,i,s){this.fn=c,this.context=i,this.once=s||!1}function p(c,i,s,o,g){if(typeof s!="function")throw new TypeError("The listener must be a function");var d=new h(s,o||c,g),l=t?t+i:i;return c._events[l]?c._events[l].fn?c._events[l]=[c._events[l],d]:c._events[l].push(d):(c._events[l]=d,c._eventsCount++),c}function I(c,i){--c._eventsCount===0?c._events=new a:delete c._events[i]}function u(){this._events=new a,this._eventsCount=0}u.prototype.eventNames=function(){var i=[],s,o;if(this._eventsCount===0)return i;for(o in s=this._events)e.call(s,o)&&i.push(t?o.slice(1):o);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(s)):i},u.prototype.listeners=function(i){var s=t?t+i:i,o=this._events[s];if(!o)return[];if(o.fn)return[o.fn];for(var g=0,d=o.length,l=new Array(d);g<d;g++)l[g]=o[g].fn;return l},u.prototype.listenerCount=function(i){var s=t?t+i:i,o=this._events[s];return o?o.fn?1:o.length:0},u.prototype.emit=function(i,s,o,g,d,l){var y=t?t+i:i;if(!this._events[y])return!1;var r=this._events[y],m=arguments.length,b,f;if(r.fn){switch(r.once&&this.removeListener(i,r.fn,void 0,!0),m){case 1:return r.fn.call(r.context),!0;case 2:return r.fn.call(r.context,s),!0;case 3:return r.fn.call(r.context,s,o),!0;case 4:return r.fn.call(r.context,s,o,g),!0;case 5:return r.fn.call(r.context,s,o,g,d),!0;case 6:return r.fn.call(r.context,s,o,g,d,l),!0}for(f=1,b=new Array(m-1);f<m;f++)b[f-1]=arguments[f];r.fn.apply(r.context,b)}else{var oe=r.length,_;for(f=0;f<oe;f++)switch(r[f].once&&this.removeListener(i,r[f].fn,void 0,!0),m){case 1:r[f].fn.call(r[f].context);break;case 2:r[f].fn.call(r[f].context,s);break;case 3:r[f].fn.call(r[f].context,s,o);break;case 4:r[f].fn.call(r[f].context,s,o,g);break;default:if(!b)for(_=1,b=new Array(m-1);_<m;_++)b[_-1]=arguments[_];r[f].fn.apply(r[f].context,b)}}return!0},u.prototype.on=function(i,s,o){return p(this,i,s,o,!1)},u.prototype.once=function(i,s,o){return p(this,i,s,o,!0)},u.prototype.removeListener=function(i,s,o,g){var d=t?t+i:i;if(!this._events[d])return this;if(!s)return I(this,d),this;var l=this._events[d];if(l.fn)l.fn===s&&(!g||l.once)&&(!o||l.context===o)&&I(this,d);else{for(var y=0,r=[],m=l.length;y<m;y++)(l[y].fn!==s||g&&!l[y].once||o&&l[y].context!==o)&&r.push(l[y]);r.length?this._events[d]=r.length===1?r[0]:r:I(this,d)}return this},u.prototype.removeAllListeners=function(i){var s;return i?(s=t?t+i:i,this._events[s]&&I(this,s)):(this._events=new a,this._eventsCount=0),this},u.prototype.off=u.prototype.removeListener,u.prototype.addListener=u.prototype.on,u.prefixed=t,u.EventEmitter=u,n.exports=u})(E)),E.exports}var D=R();const N=S(D);class T extends Error{}T.prototype.name="InvalidTokenError";function z(n){return decodeURIComponent(atob(n).replace(/(.)/g,(e,t)=>{let a=t.charCodeAt(0).toString(16).toUpperCase();return a.length<2&&(a="0"+a),"%"+a}))}function B(n){let e=n.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return z(e)}catch{return atob(e)}}function F(n,e){if(typeof n!="string")throw new T("Invalid token specified: must be a string");e||(e={});const t=e.header===!0?0:1,a=n.split(".")[t];if(typeof a!="string")throw new T(`Invalid token specified: missing part #${t+1}`);let h;try{h=B(a)}catch(p){throw new T(`Invalid token specified: invalid base64 for part #${t+1} (${p.message})`)}try{return JSON.parse(h)}catch(p){throw new T(`Invalid token specified: invalid json for part #${t+1} (${p.message})`)}}var M=typeof global=="object"&&global&&global.Object===Object&&global,V=typeof self=="object"&&self&&self.Object===Object&&self,J=M||V||Function("return this")(),j=J.Symbol,A=Object.prototype,U=A.hasOwnProperty,q=A.toString,O=j?j.toStringTag:void 0;function H(n){var e=U.call(n,O),t=n[O];try{n[O]=void 0;var a=!0}catch{}var h=q.call(n);return a&&(e?n[O]=t:delete n[O]),h}var K=Object.prototype,Y=K.toString;function Q(n){return Y.call(n)}var W="[object Null]",X="[object Undefined]",P=j?j.toStringTag:void 0;function Z(n){return n==null?n===void 0?X:W:P&&P in Object(n)?H(n):Q(n)}var ee=Array.isArray;function te(n){return n!=null&&typeof n=="object"}var ne="[object String]";function re(n){return typeof n=="string"||!ee(n)&&te(n)&&Z(n)==ne}var G=(n=>(n.INIT="init",n.VERIFYING="verifying",n.VERIFIED="verified",n.REFRESH="refresh",n.ERROR="error",n))(G||{});let k;class L extends N{#t="";#e={};#o=0;#c;#i=!1;#s=!1;#r=!1;#l=!1;#a;#f;#n;constructor({googleId:e,prefix:t="aAuth",root:a="/api"}){if(super(),this.#c=e,this.#f=t,this.#n=a,this.#a=Date.now()/1e3>>0,this.setAccessToken(localStorage.getItem(this.localKey)||"",!1),this.#t){this.verifyToken().then(h=>{h||this.initGoogleIdentity()});return}this.initGoogleIdentity()}get accessToken(){return this.#t}get expiredIn(){return this.#o?0:this.#o-this.#a}get isVerifying(){return this.#s}get isVerified(){return this.#r}get localKey(){return`${this.#f}-token`}get root(){return this.#n}get user(){return this.#e}doSignIn(){this.initGoogleIdentity()}doSignOut(){const e=this.getRevokeHint();this.setAccessToken(""),this.#e={},this.#r=!1,clearInterval(k),this.emit("verified",!1),e&&"google"in globalThis&&"accounts"in globalThis.google&&google.accounts.id.revoke(e)}async store(e,t){t=re(t)?t:JSON.stringify(t),await fetch(`${this.#n}/store`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#t}`},body:JSON.stringify({key:e,value:t})})}async retrieve(e){const t=await fetch(`${this.#n}/retrieve`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#t}`},body:JSON.stringify({key:e})}),{data:a}=await t.json();return a?.value}initGoogleIdentity(){this.#i||(this.emit("init",!0),this.#i=!0,this.ensureGoogleIdentityInitialized().then(()=>{google.accounts.id.prompt(e=>{this.handlePromptMoment(e)})}).catch(e=>{this.#i=!1,this.emit("init",!1),this.emit("error",e.message||String(e))}))}async renderButton(e,t){if(e){try{await this.ensureGoogleIdentityInitialized()}catch(a){this.emit("error",a.message||String(a));return}if(!x()){this.emit("error","Google Identity Services 未加载完成");return}google.accounts.id.renderButton(e,{type:"standard",theme:"outline",size:"large",text:"signin_with",...t})}}async ensureGoogleIdentityInitialized(){if(await ie(),!x())throw new Error("Google Identity Services 未加载完成");this.#l||(google.accounts.id.initialize({client_id:this.#c,callback:e=>this.onGoogleIdentityCallback(e),auto_select:!0,ux_mode:"popup"}),this.#l=!0)}handlePromptMoment(e){(e.isNotDisplayed()||e.isSkippedMoment()||e.isDismissedMoment())&&(this.#i=!1,this.emit("init",!1))}refreshCountDown(){this.#a=Date.now()/1e3>>0,this.expiredIn<=60&&(clearInterval(k),this.refreshToken())}async refreshToken(){this.emit("refresh",!0);const e=await fetch(`${this.#n}/refresh-token`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#t}`}}),{data:t}=await e.json(),{token:a}=t;this.setAccessToken(a),this.emit("refresh",!1)}setAccessToken(e,t=!0){if(this.#t=e,t&&localStorage.setItem(this.localKey,e),!e){this.#e={},this.#o=0;return}try{this.#e=F(e)}catch{this.#e={}}this.#o=this.#e.exp||0,this.expiredIn>0&&(clearInterval(k),k=setInterval(()=>this.refreshCountDown(),1e3))}async verifyToken(){this.emit("verifying",!0),this.#s=!0;try{const e=await fetch(`${this.#n}/verify-auth`,{method:"POST",headers:{"Content-type":"application/json",Authorization:`Bearer ${this.#t}`}}),{data:t}=await e.json();t&&(this.#e=t,this.#r=!0,this.emit("verified",!0))}catch(e){this.#r=!1,this.emit("error",e.message||String(e))}return this.emit("verifying",!1),this.#s=!1,this.#r}async onGoogleIdentityCallback(e){this.emit("init",!1),this.#i=!1,this.emit("verifying",!0),this.#s=!0;const t=await fetch(`${this.#n}/google-auth`,{method:"POST",headers:{"Content-type":"application/json"},body:JSON.stringify({credential:e.credential})}),{data:a}=await t.json();a||this.emit("error","Failed to validate user.");const{token:h}=a;this.setAccessToken(h),this.emit("verifying",!1),this.#s=!1,this.emit("verified",!0),this.#r=!0}getRevokeHint(){const e=this.#e.email;if(typeof e=="string"&&e.trim())return e;const t=this.#e.sub;return typeof t=="string"&&t.trim()?t:""}}let w=null;function x(){return"google"in globalThis&&"accounts"in globalThis.google}function ie(){return x()?Promise.resolve():w||(w=new Promise((n,e)=>{const t="https://accounts.google.com/gsi/client",a=document.querySelector(`script[src="${t}"]`),h=a||document.createElement("script");function p(){n()}function I(){e(new Error("Google Identity Services 加载失败"))}h.addEventListener("load",p,{once:!0}),h.addEventListener("error",I,{once:!0}),a||(h.src=t,h.async=!0,document.head.appendChild(h))}),w.catch(()=>{w=null}),w)}let C;function se(n){return C=C||new L(n),C}v.AwesomeAuth=L,v.AwesomeAuthEvent=G,v.getInstance=se,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roudanio/awesome-auth",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "main": "dist/awesome-auth.umd.js",
6
6
  "module": "dist/awesome-auth.js",
@@ -27,6 +27,7 @@ describe('AwesomeAuth One Tap', () => {
27
27
  let promptCallbacks: PromptCallback[];
28
28
  let initialize: ReturnType<typeof vi.fn>;
29
29
  let prompt: ReturnType<typeof vi.fn>;
30
+ let revoke: ReturnType<typeof vi.fn>;
30
31
 
31
32
  beforeEach(() => {
32
33
  promptCallbacks = [];
@@ -36,12 +37,14 @@ describe('AwesomeAuth One Tap', () => {
36
37
  promptCallbacks.push(callback);
37
38
  }
38
39
  });
40
+ revoke = vi.fn();
39
41
 
40
42
  const googleMock = {
41
43
  accounts: {
42
44
  id: {
43
45
  initialize,
44
46
  prompt,
47
+ revoke,
45
48
  },
46
49
  },
47
50
  };
@@ -79,34 +82,73 @@ describe('AwesomeAuth One Tap', () => {
79
82
  vi.clearAllMocks();
80
83
  });
81
84
 
82
- it('在提示被关闭后重置初始化状态,并允许再次唤起', () => {
85
+ it('在提示被关闭后重置初始化状态,并允许再次唤起', async () => {
83
86
  const events: boolean[] = [];
84
87
  const auth = new AwesomeAuth({ googleId: 'test-client' });
85
88
  auth.on(AwesomeAuthEvent.INIT, (value: boolean) => {
86
89
  events.push(value);
87
90
  });
88
91
 
92
+ await flushPromises();
89
93
  expect(promptCallbacks).toHaveLength(1);
90
94
  promptCallbacks[0](createPromptNotification('dismissed'));
91
95
 
92
96
  expect(events).toEqual([false]);
93
97
 
94
98
  auth.doSignIn();
99
+ await flushPromises();
95
100
  expect(promptCallbacks).toHaveLength(2);
96
101
  expect(events[1]).toBe(true);
97
102
  expect(initialize).toHaveBeenCalledTimes(1);
98
103
  });
99
104
 
100
- it('在提示未显示时结束初始化状态', () => {
105
+ it('在提示未显示时结束初始化状态', async () => {
101
106
  const events: boolean[] = [];
102
107
  const auth = new AwesomeAuth({ googleId: 'test-client' });
103
108
  auth.on(AwesomeAuthEvent.INIT, (value: boolean) => {
104
109
  events.push(value);
105
110
  });
106
111
 
112
+ await flushPromises();
107
113
  expect(promptCallbacks).toHaveLength(1);
108
114
  promptCallbacks[0](createPromptNotification('not-displayed'));
109
115
 
110
116
  expect(events).toEqual([false]);
111
117
  });
118
+
119
+ it('未提供 hint 时不调用 revoke', () => {
120
+ const auth = new AwesomeAuth({ googleId: 'test-client' });
121
+
122
+ auth.doSignOut();
123
+
124
+ expect(revoke).not.toHaveBeenCalled();
125
+ });
126
+
127
+ it('使用 email 作为 hint 调用 revoke', () => {
128
+ const token = createJwt({
129
+ email: 'test@example.com',
130
+ sub: 'sub-123',
131
+ });
132
+
133
+ const auth = new AwesomeAuth({ googleId: 'test-client' });
134
+ (auth as unknown as { setAccessToken: (value: string, local?: boolean) => void }).setAccessToken(token, false);
135
+
136
+ auth.doSignOut();
137
+
138
+ expect(revoke).toHaveBeenCalledWith('test@example.com');
139
+ });
112
140
  });
141
+
142
+ function createJwt(payload: Record<string, unknown>): string {
143
+ const header = encodeBase64Url(JSON.stringify({ alg: 'none', typ: 'JWT' }));
144
+ const body = encodeBase64Url(JSON.stringify(payload));
145
+ return `${header}.${body}.`;
146
+ }
147
+
148
+ function encodeBase64Url(value: string): string {
149
+ return Buffer.from(value, 'utf-8').toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
150
+ }
151
+
152
+ async function flushPromises(): Promise<void> {
153
+ await new Promise((resolve) => setTimeout(resolve, 0));
154
+ }
@@ -1 +1 @@
1
- {"root":["./src/auth.ts","./src/main.ts","./src/vite-env.d.ts","./src/app.vue"],"errors":true,"version":"5.9.3"}
1
+ {"root":["./src/auth.ts","./src/main.ts","./src/vite-env.d.ts","./src/app.vue"],"version":"5.9.3"}