@roudanio/awesome-auth 0.1.1 → 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 A(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var k={exports:{}};(function(e){var n=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)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 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 r=this._events[g],y=arguments.length,b,f;if(r.fn){switch(r.once&&this.removeListener(i,r.fn,void 0,!0),y){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,p),!0;case 5:return r.fn.call(r.context,s,o,p,u),!0;case 6:return r.fn.call(r.context,s,o,p,u,l),!0}for(f=1,b=new Array(y-1);f<y;f++)b[f-1]=arguments[f];r.fn.apply(r.context,b)}else{var ne=r.length,T;for(f=0;f<ne;f++)switch(r[f].once&&this.removeListener(i,r[f].fn,void 0,!0),y){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,p);break;default:if(!b)for(T=1,b=new Array(y-1);T<y;T++)b[T-1]=arguments[T];r[f].fn.apply(r[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,r=[],y=l.length;g<y;g++)(l[g].fn!==s||p&&!l[g].once||o&&l[g].context!==o)&&r.push(l[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})(k);var P=k.exports;const G=A(P);class w extends Error{}w.prototype.name="InvalidTokenError";function L(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 N(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 L(n)}catch{return atob(n)}}function D(e,n){if(typeof e!="string")throw new w("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 w(`Invalid token specified: missing part #${t+1}`);let d;try{d=N(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 R=typeof global=="object"&&global&&global.Object===Object&&global,F=typeof self=="object"&&self&&self.Object===Object&&self,V=R||F||Function("return this")(),O=V.Symbol,C=Object.prototype,z=C.hasOwnProperty,J=C.toString,S=O?O.toStringTag:void 0;function U(e){var n=z.call(e,S),t=e[S];try{e[S]=void 0;var a=!0}catch{}var d=J.call(e);return a&&(n?e[S]=t:delete e[S]),d}var B=Object.prototype,K=B.toString;function M(e){return K.call(e)}var q="[object Null]",H="[object Undefined]",E=O?O.toStringTag:void 0;function Y(e){return e==null?e===void 0?H:q:E&&E in Object(e)?U(e):M(e)}var Q=Array.isArray;function W(e){return e!=null&&typeof e=="object"}var X="[object String]";function Z(e){return typeof e=="string"||!Q(e)&&W(e)&&Y(e)==X}var x=(e=>(e.INIT="init",e.VERIFYING="verifying",e.VERIFIED="verified",e.REFRESH="refresh",e.ERROR="error",e))(x||{});let _;class $ extends G{#e="";#t={};#s=0;#c;#o=!1;#r=!1;#i=!1;#a;#l;#n;constructor({googleId:n,prefix:t="aAuth",root:a="/api"}){if(super(),this.#c=n,this.#l=t,this.#n=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.#r}get isVerified(){return this.#i}get localKey(){return`${this.#l}-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=Z(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)){ee(),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(_),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=D(n)}catch{this.#t={}}this.#s=this.#t.exp||0,this.expiredIn>0&&(clearInterval(_),_=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:d}=a;this.setAccessToken(d),this.emit("verifying",!1),this.#r=!1,this.emit("verified",!0),this.#i=!0}}function ee(){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 j;function te(e){return j=j||new $(e),j}return m.AwesomeAuth=$,m.AwesomeAuthEvent=x,m.getInstance=te,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,350 +1,398 @@
1
- function E(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 k = { exports: {} };
5
- (function(e) {
6
- var r = Object.prototype.hasOwnProperty, t = "~";
7
- function a() {
8
- }
9
- Object.create && (a.prototype = /* @__PURE__ */ Object.create(null), new a().__proto__ || (t = !1));
10
- function d(c, i, s) {
11
- this.fn = c, this.context = i, this.once = s || !1;
12
- }
13
- function v(c, i, s, o, p) {
14
- if (typeof s != "function")
15
- throw new TypeError("The listener must be a function");
16
- var u = new d(s, o || c, p), l = t ? t + i : i;
17
- 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;
18
- }
19
- function S(c, i) {
20
- --c._eventsCount === 0 ? c._events = new a() : delete c._events[i];
21
- }
22
- function h() {
23
- this._events = new a(), this._eventsCount = 0;
24
- }
25
- h.prototype.eventNames = function() {
26
- var i = [], s, o;
27
- if (this._eventsCount === 0) return i;
28
- for (o in s = this._events)
29
- r.call(s, o) && i.push(t ? o.slice(1) : o);
30
- return Object.getOwnPropertySymbols ? i.concat(Object.getOwnPropertySymbols(s)) : i;
31
- }, h.prototype.listeners = function(i) {
32
- var s = t ? t + i : i, o = this._events[s];
33
- if (!o) return [];
34
- if (o.fn) return [o.fn];
35
- for (var p = 0, u = o.length, l = new Array(u); p < u; p++)
36
- l[p] = o[p].fn;
37
- return l;
38
- }, h.prototype.listenerCount = function(i) {
39
- var s = t ? t + i : i, o = this._events[s];
40
- return o ? o.fn ? 1 : o.length : 0;
41
- }, h.prototype.emit = function(i, s, o, p, u, l) {
42
- var g = t ? t + i : i;
43
- if (!this._events[g]) return !1;
44
- var n = this._events[g], y = arguments.length, b, f;
45
- if (n.fn) {
46
- switch (n.once && this.removeListener(i, n.fn, void 0, !0), y) {
47
- case 1:
48
- return n.fn.call(n.context), !0;
49
- case 2:
50
- return n.fn.call(n.context, s), !0;
51
- case 3:
52
- return n.fn.call(n.context, s, o), !0;
53
- case 4:
54
- return n.fn.call(n.context, s, o, p), !0;
55
- case 5:
56
- return n.fn.call(n.context, s, o, p, u), !0;
57
- case 6:
58
- return n.fn.call(n.context, s, o, p, u, l), !0;
59
- }
60
- for (f = 1, b = new Array(y - 1); f < y; f++)
61
- b[f - 1] = arguments[f];
62
- n.fn.apply(n.context, b);
63
- } else {
64
- var C = n.length, m;
65
- for (f = 0; f < C; f++)
66
- switch (n[f].once && this.removeListener(i, n[f].fn, void 0, !0), y) {
4
+ var j = { exports: {} }, E;
5
+ function A() {
6
+ return E || (E = 1, (function(r) {
7
+ var e = Object.prototype.hasOwnProperty, t = "~";
8
+ function a() {
9
+ }
10
+ Object.create && (a.prototype = /* @__PURE__ */ Object.create(null), new a().__proto__ || (t = !1));
11
+ function f(c, i, s) {
12
+ this.fn = c, this.context = i, this.once = s || !1;
13
+ }
14
+ function p(c, i, s, o, g) {
15
+ if (typeof s != "function")
16
+ throw new TypeError("The listener must be a function");
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
+ }
20
+ function b(c, i) {
21
+ --c._eventsCount === 0 ? c._events = new a() : delete c._events[i];
22
+ }
23
+ function u() {
24
+ this._events = new a(), this._eventsCount = 0;
25
+ }
26
+ u.prototype.eventNames = function() {
27
+ var i = [], s, o;
28
+ if (this._eventsCount === 0) return i;
29
+ for (o in s = this._events)
30
+ e.call(s, o) && i.push(t ? o.slice(1) : o);
31
+ return Object.getOwnPropertySymbols ? i.concat(Object.getOwnPropertySymbols(s)) : i;
32
+ }, u.prototype.listeners = function(i) {
33
+ var s = t ? t + i : i, o = this._events[s];
34
+ if (!o) return [];
35
+ if (o.fn) return [o.fn];
36
+ for (var g = 0, d = o.length, l = new Array(d); g < d; g++)
37
+ l[g] = o[g].fn;
38
+ return l;
39
+ }, u.prototype.listenerCount = function(i) {
40
+ var s = t ? t + i : i, o = this._events[s];
41
+ return o ? o.fn ? 1 : o.length : 0;
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
+ if (n.fn) {
47
+ switch (n.once && this.removeListener(i, n.fn, void 0, !0), v) {
67
48
  case 1:
68
- n[f].fn.call(n[f].context);
69
- break;
49
+ return n.fn.call(n.context), !0;
70
50
  case 2:
71
- n[f].fn.call(n[f].context, s);
72
- break;
51
+ return n.fn.call(n.context, s), !0;
73
52
  case 3:
74
- n[f].fn.call(n[f].context, s, o);
75
- break;
53
+ return n.fn.call(n.context, s, o), !0;
76
54
  case 4:
77
- n[f].fn.call(n[f].context, s, o, p);
78
- break;
79
- default:
80
- if (!b) for (m = 1, b = new Array(y - 1); m < y; m++)
81
- b[m - 1] = arguments[m];
82
- n[f].fn.apply(n[f].context, b);
55
+ return n.fn.call(n.context, s, o, g), !0;
56
+ case 5:
57
+ return n.fn.call(n.context, s, o, g, d), !0;
58
+ case 6:
59
+ return n.fn.call(n.context, s, o, g, d, l), !0;
83
60
  }
84
- }
85
- return !0;
86
- }, h.prototype.on = function(i, s, o) {
87
- return v(this, i, s, o, !1);
88
- }, h.prototype.once = function(i, s, o) {
89
- return v(this, i, s, o, !0);
90
- }, h.prototype.removeListener = function(i, s, o, p) {
91
- var u = t ? t + i : i;
92
- if (!this._events[u]) return this;
93
- if (!s)
94
- return S(this, u), this;
95
- var l = this._events[u];
96
- if (l.fn)
97
- l.fn === s && (!p || l.once) && (!o || l.context === o) && S(this, u);
98
- else {
99
- for (var g = 0, n = [], y = l.length; g < y; g++)
100
- (l[g].fn !== s || p && !l[g].once || o && l[g].context !== o) && n.push(l[g]);
101
- n.length ? this._events[u] = n.length === 1 ? n[0] : n : S(this, u);
102
- }
103
- return this;
104
- }, h.prototype.removeAllListeners = function(i) {
105
- var s;
106
- return i ? (s = t ? t + i : i, this._events[s] && S(this, s)) : (this._events = new a(), this._eventsCount = 0), this;
107
- }, h.prototype.off = h.prototype.removeListener, h.prototype.addListener = h.prototype.on, h.prefixed = t, h.EventEmitter = h, e.exports = h;
108
- })(k);
109
- var $ = k.exports;
110
- const P = /* @__PURE__ */ E($);
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
+ } else {
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
+ case 1:
69
+ n[h].fn.call(n[h].context);
70
+ break;
71
+ case 2:
72
+ n[h].fn.call(n[h].context, s);
73
+ break;
74
+ case 3:
75
+ n[h].fn.call(n[h].context, s, o);
76
+ break;
77
+ case 4:
78
+ n[h].fn.call(n[h].context, s, o, g);
79
+ break;
80
+ default:
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
+ }
85
+ }
86
+ return !0;
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
+ if (!s)
95
+ return b(this, d), this;
96
+ var l = this._events[d];
97
+ if (l.fn)
98
+ l.fn === s && (!g || l.once) && (!o || l.context === o) && b(this, d);
99
+ else {
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
+ }
104
+ return this;
105
+ }, u.prototype.removeAllListeners = function(i) {
106
+ var s;
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
+ }
111
+ var L = A();
112
+ const R = /* @__PURE__ */ G(L);
111
113
  class T extends Error {
112
114
  }
113
115
  T.prototype.name = "InvalidTokenError";
114
- function A(e) {
115
- return decodeURIComponent(atob(e).replace(/(.)/g, (r, t) => {
116
+ function D(r) {
117
+ return decodeURIComponent(atob(r).replace(/(.)/g, (e, t) => {
116
118
  let a = t.charCodeAt(0).toString(16).toUpperCase();
117
119
  return a.length < 2 && (a = "0" + a), "%" + a;
118
120
  }));
119
121
  }
120
- function G(e) {
121
- let r = e.replace(/-/g, "+").replace(/_/g, "/");
122
- switch (r.length % 4) {
122
+ function N(r) {
123
+ let e = r.replace(/-/g, "+").replace(/_/g, "/");
124
+ switch (e.length % 4) {
123
125
  case 0:
124
126
  break;
125
127
  case 2:
126
- r += "==";
128
+ e += "==";
127
129
  break;
128
130
  case 3:
129
- r += "=";
131
+ e += "=";
130
132
  break;
131
133
  default:
132
134
  throw new Error("base64 string is not of the correct length");
133
135
  }
134
136
  try {
135
- return A(r);
137
+ return D(e);
136
138
  } catch {
137
- return atob(r);
139
+ return atob(e);
138
140
  }
139
141
  }
140
- function L(e, r) {
141
- if (typeof e != "string")
142
+ function z(r, e) {
143
+ if (typeof r != "string")
142
144
  throw new T("Invalid token specified: must be a string");
143
- r || (r = {});
144
- 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];
145
147
  if (typeof a != "string")
146
148
  throw new T(`Invalid token specified: missing part #${t + 1}`);
147
- let d;
149
+ let f;
148
150
  try {
149
- d = G(a);
150
- } catch (v) {
151
- 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})`);
152
154
  }
153
155
  try {
154
- return JSON.parse(d);
155
- } catch (v) {
156
- 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})`);
157
159
  }
158
160
  }
159
- var N = typeof global == "object" && global && global.Object === Object && global, D = typeof self == "object" && self && self.Object === Object && self, R = N || D || Function("return this")(), O = R.Symbol, x = Object.prototype, F = x.hasOwnProperty, V = x.toString, w = O ? O.toStringTag : void 0;
160
- function z(e) {
161
- var r = F.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];
162
164
  try {
163
- e[w] = void 0;
165
+ r[S] = void 0;
164
166
  var a = !0;
165
167
  } catch {
166
168
  }
167
- var d = V.call(e);
168
- 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;
169
171
  }
170
- var J = Object.prototype, U = J.toString;
171
- function B(e) {
172
- return U.call(e);
172
+ var q = Object.prototype, H = q.toString;
173
+ function K(r) {
174
+ return H.call(r);
173
175
  }
174
- var K = "[object Null]", q = "[object Undefined]", j = O ? O.toStringTag : void 0;
175
- function H(e) {
176
- return e == null ? e === void 0 ? q : K : j && j in Object(e) ? z(e) : B(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);
177
179
  }
178
- var M = Array.isArray;
179
- function Y(e) {
180
- return e != null && typeof e == "object";
180
+ var X = Array.isArray;
181
+ function Z(r) {
182
+ return r != null && typeof r == "object";
181
183
  }
182
- var Q = "[object String]";
183
- function W(e) {
184
- return typeof e == "string" || !M(e) && Y(e) && H(e) == Q;
184
+ var ee = "[object String]";
185
+ function te(r) {
186
+ return typeof r == "string" || !X(r) && Z(r) && W(r) == ee;
185
187
  }
186
- var X = /* @__PURE__ */ ((e) => (e.INIT = "init", e.VERIFYING = "verifying", e.VERIFIED = "verified", e.REFRESH = "refresh", e.ERROR = "error", e))(X || {});
188
+ var re = /* @__PURE__ */ ((r) => (r.INIT = "init", r.VERIFYING = "verifying", r.VERIFIED = "verified", r.REFRESH = "refresh", r.ERROR = "error", r))(re || {});
187
189
  let _;
188
- class Z extends P {
189
- #e = "";
190
- #t = {};
191
- #s = 0;
190
+ class ne extends R {
191
+ #t = "";
192
+ #e = {};
193
+ #o = 0;
192
194
  #c;
193
- #o = !1;
194
- #n = !1;
195
195
  #i = !1;
196
+ #s = !1;
197
+ #n = !1;
198
+ #l = !1;
196
199
  #a;
197
- #l;
200
+ #h;
198
201
  #r;
199
- constructor({
200
- googleId: r,
201
- prefix: t = "aAuth",
202
- root: a = "/api"
203
- }) {
204
- 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) {
205
- this.verifyToken().then((d) => {
206
- 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();
207
206
  });
208
207
  return;
209
208
  }
210
209
  this.initGoogleIdentity();
211
210
  }
212
211
  get accessToken() {
213
- return this.#e;
212
+ return this.#t;
214
213
  }
215
214
  get expiredIn() {
216
- return this.#s ? 0 : this.#s - this.#a;
215
+ return this.#o ? 0 : this.#o - this.#a;
217
216
  }
218
217
  get isVerifying() {
219
- return this.#n;
218
+ return this.#s;
220
219
  }
221
220
  get isVerified() {
222
- return this.#i;
221
+ return this.#n;
223
222
  }
224
223
  get localKey() {
225
- return `${this.#l}-token`;
224
+ return `${this.#h}-token`;
226
225
  }
227
226
  get root() {
228
227
  return this.#r;
229
228
  }
230
229
  get user() {
231
- return this.#t;
230
+ return this.#e;
232
231
  }
233
232
  doSignIn() {
234
233
  this.initGoogleIdentity();
235
234
  }
236
235
  doSignOut() {
237
- 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);
238
238
  }
239
- async store(r, t) {
240
- t = W(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`, {
241
241
  method: "POST",
242
242
  headers: {
243
243
  "Content-type": "application/json",
244
- Authorization: `Bearer ${this.#e}`
244
+ Authorization: `Bearer ${this.#t}`
245
245
  },
246
246
  body: JSON.stringify({
247
- key: r,
247
+ key: e,
248
248
  value: t
249
249
  })
250
250
  });
251
251
  }
252
- async retrieve(r) {
252
+ async retrieve(e) {
253
253
  const t = await fetch(`${this.#r}/retrieve`, {
254
254
  method: "POST",
255
255
  headers: {
256
256
  "Content-type": "application/json",
257
- Authorization: `Bearer ${this.#e}`
257
+ Authorization: `Bearer ${this.#t}`
258
258
  },
259
259
  body: JSON.stringify({
260
- key: r
260
+ key: e
261
261
  })
262
262
  }), { data: a } = await t.json();
263
263
  return a?.value;
264
264
  }
265
265
  initGoogleIdentity() {
266
- if (!("google" in globalThis) || !("accounts" in globalThis.google)) {
267
- ee(), globalThis.onGoogleLibraryLoad = () => this.initGoogleIdentity();
268
- 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
+ });
269
293
  }
270
- 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({
271
299
  client_id: this.#c,
272
- callback: (r) => this.onGoogleIdentityCallback(r),
300
+ callback: (e) => this.onGoogleIdentityCallback(e),
273
301
  auto_select: !0,
274
302
  ux_mode: "popup"
275
- }), 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));
276
307
  }
277
308
  refreshCountDown() {
278
309
  this.#a = Date.now() / 1e3 >> 0, this.expiredIn <= 60 && (clearInterval(_), this.refreshToken());
279
310
  }
280
311
  async refreshToken() {
281
312
  this.emit("refresh", !0);
282
- const r = await fetch(`${this.#r}/refresh-token`, {
313
+ const e = await fetch(`${this.#r}/refresh-token`, {
283
314
  method: "POST",
284
315
  headers: {
285
316
  "Content-type": "application/json",
286
- Authorization: `Bearer ${this.#e}`
317
+ Authorization: `Bearer ${this.#t}`
287
318
  }
288
- }), { data: t } = await r.json(), { token: a } = t;
319
+ }), { data: t } = await e.json(), { token: a } = t;
289
320
  this.setAccessToken(a), this.emit("refresh", !1);
290
321
  }
291
- setAccessToken(r, t = !0) {
292
- if (this.#e = r, t && localStorage.setItem(this.localKey, r), !r) {
293
- 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;
294
325
  return;
295
326
  }
296
327
  try {
297
- this.#t = L(r);
328
+ this.#e = z(e);
298
329
  } catch {
299
- this.#t = {};
330
+ this.#e = {};
300
331
  }
301
- this.#s = this.#t.exp || 0, this.expiredIn > 0 && (clearInterval(_), _ = setInterval(() => this.refreshCountDown(), 1e3));
332
+ this.#o = this.#e.exp || 0, this.expiredIn > 0 && (clearInterval(_), _ = setInterval(() => this.refreshCountDown(), 1e3));
302
333
  }
303
334
  async verifyToken() {
304
- this.emit("verifying", !0), this.#n = !0;
335
+ this.emit("verifying", !0), this.#s = !0;
305
336
  try {
306
- const r = await fetch(`${this.#r}/verify-auth`, {
337
+ const e = await fetch(`${this.#r}/verify-auth`, {
307
338
  method: "POST",
308
339
  headers: {
309
340
  "Content-type": "application/json",
310
- Authorization: `Bearer ${this.#e}`
341
+ Authorization: `Bearer ${this.#t}`
311
342
  }
312
- }), { data: t } = await r.json();
313
- t && (this.#t = t, this.#i = !0, this.emit("verified", !0));
314
- } catch (r) {
315
- 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));
316
347
  }
317
- return this.emit("verifying", !1), this.#n = !1, this.#i;
348
+ return this.emit("verifying", !1), this.#s = !1, this.#n;
318
349
  }
319
- async onGoogleIdentityCallback(r) {
320
- 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;
321
352
  const t = await fetch(`${this.#r}/google-auth`, {
322
353
  method: "POST",
323
354
  headers: {
324
355
  "Content-type": "application/json"
325
356
  },
326
357
  body: JSON.stringify({
327
- credential: r.credential
358
+ credential: e.credential
328
359
  })
329
360
  }), { data: a } = await t.json();
330
361
  a || this.emit("error", "Failed to validate user.");
331
- const { token: d } = a;
332
- 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;
333
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 : "";
370
+ }
371
+ }
372
+ let w = null;
373
+ function x() {
374
+ return "google" in globalThis && "accounts" in globalThis.google;
334
375
  }
335
- function ee() {
336
- const e = "https://accounts.google.com/gsi/client";
337
- if (document.querySelector(`script[src="${e}"]`))
338
- return;
339
- const r = document.createElement("script");
340
- r.src = e, r.async = !0, document.head.appendChild(r);
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);
341
389
  }
342
- let I;
343
- function te(e) {
344
- return I = I || new Z(e), I;
390
+ let k;
391
+ function se(r) {
392
+ return k = k || new ne(r), k;
345
393
  }
346
394
  export {
347
- Z as AwesomeAuth,
348
- X as AwesomeAuthEvent,
349
- te as getInstance
395
+ ne as AwesomeAuth,
396
+ re as AwesomeAuthEvent,
397
+ se as getInstance
350
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 x={exports:{}};(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 ne=r.length,O;for(l=0;l<ne;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})(x);var P=x.exports;const G=w(P);class T extends Error{}T.prototype.name="InvalidTokenError";function L(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 N(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 L(n)}catch{return atob(n)}}function D(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=N(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 R=typeof global=="object"&&global&&global.Object===Object&&global,F=typeof self=="object"&&self&&self.Object===Object&&self,V=R||F||Function("return this")(),j=V.Symbol,C=Object.prototype,z=C.hasOwnProperty,J=C.toString,S=j?j.toStringTag:void 0;function U(e){var n=z.call(e,S),t=e[S];try{e[S]=void 0;var a=!0}catch{}var p=J.call(e);return a&&(n?e[S]=t:delete e[S]),p}var B=Object.prototype,K=B.toString;function M(e){return K.call(e)}var q="[object Null]",H="[object Undefined]",E=j?j.toStringTag:void 0;function Y(e){return e==null?e===void 0?H:q:E&&E in Object(e)?U(e):M(e)}var Q=Array.isArray;function W(e){return e!=null&&typeof e=="object"}var X="[object String]";function Z(e){return typeof e=="string"||!Q(e)&&W(e)&&Y(e)==X}var $=(e=>(e.INIT="init",e.VERIFYING="verifying",e.VERIFIED="verified",e.REFRESH="refresh",e.ERROR="error",e))($||{});let _;class A extends G{#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=Z(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)){ee(),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(_),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=D(n)}catch{this.#t={}}this.#s=this.#t.exp||0,this.expiredIn>0&&(clearInterval(_),_=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 ee(){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 k;function te(e){return k=k||new A(e),k}y.AwesomeAuth=A,y.AwesomeAuthEvent=$,y.getInstance=te,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.1",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "main": "dist/awesome-auth.umd.js",
6
6
  "module": "dist/awesome-auth.js",
@@ -8,29 +8,33 @@
8
8
  "types": "dist/auth.d.ts",
9
9
  "dependencies": {
10
10
  "eventemitter3": "^5.0.1",
11
- "google-auth-library": "^9.14.2",
12
- "jsonwebtoken": "^9.0.2",
11
+ "google-auth-library": "^10.5.0",
12
+ "jsonwebtoken": "^9.0.3",
13
13
  "jwt-decode": "^4.0.0",
14
- "lodash-es": "^4.17.21",
15
- "vue": "^3.5.12",
16
- "@awesome-comment/core": "0.1.0"
14
+ "lodash-es": "^4.17.22",
15
+ "vue": "^3.5.26",
16
+ "@awesome-comment/core": "0.1.1"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/gapi": "^0.0.47",
20
20
  "@types/gapi.auth2": "^0.0.61",
21
- "@types/google.accounts": "^0.0.15",
22
- "@types/jsonwebtoken": "^9.0.7",
23
- "@vitejs/plugin-vue": "^5.1.4",
24
- "autoprefixer": "^10.4.20",
25
- "postcss": "^8.4.47",
26
- "tailwindcss": "^3.4.14",
27
- "typescript": "^5.6.3",
28
- "vite": "^5.4.10",
29
- "vite-plugin-dts": "^4.3.0",
30
- "vue-tsc": "^2.1.10"
21
+ "@types/google.accounts": "^0.0.18",
22
+ "@types/jsonwebtoken": "^9.0.10",
23
+ "@types/lodash-es": "^4.17.12",
24
+ "@vitejs/plugin-vue": "^6.0.3",
25
+ "autoprefixer": "^10.4.23",
26
+ "postcss": "^8.5.6",
27
+ "tailwindcss": "^3.4.19",
28
+ "typescript": "^5.9.3",
29
+ "vite": "^7.3.1",
30
+ "vite-plugin-dts": "^4.5.4",
31
+ "vitest": "^4.0.17",
32
+ "vue-tsc": "^3.2.2"
31
33
  },
32
34
  "scripts": {
33
35
  "dev": "vite",
34
- "build": "vue-tsc -b && vite build"
36
+ "build": "vue-tsc -b && vite build",
37
+ "test": "vitest",
38
+ "test:run": "vitest run"
35
39
  }
36
40
  }
@@ -0,0 +1,154 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import { AwesomeAuth, AwesomeAuthEvent } from '../../src/auth';
3
+
4
+ type PromptCallback = (notification: google.accounts.id.PromptMomentNotification) => void;
5
+
6
+ type PromptState = 'not-displayed' | 'skipped' | 'dismissed' | 'displayed';
7
+
8
+ function createPromptNotification(state: PromptState): google.accounts.id.PromptMomentNotification {
9
+ return {
10
+ isDisplayMoment: () => state === 'displayed' || state === 'not-displayed',
11
+ isDisplayed: () => state === 'displayed',
12
+ isNotDisplayed: () => state === 'not-displayed',
13
+ getNotDisplayedReason: () => 'suppressed_by_user',
14
+ isSkippedMoment: () => state === 'skipped',
15
+ getSkippedReason: () => 'user_cancel',
16
+ isDismissedMoment: () => state === 'dismissed',
17
+ getDismissedReason: () => 'cancel_called',
18
+ getMomentType: () => {
19
+ if (state === 'skipped') return 'skipped';
20
+ if (state === 'dismissed') return 'dismissed';
21
+ return 'display';
22
+ },
23
+ } as unknown as google.accounts.id.PromptMomentNotification;
24
+ }
25
+
26
+ describe('AwesomeAuth One Tap', () => {
27
+ let promptCallbacks: PromptCallback[];
28
+ let initialize: ReturnType<typeof vi.fn>;
29
+ let prompt: ReturnType<typeof vi.fn>;
30
+ let revoke: ReturnType<typeof vi.fn>;
31
+
32
+ beforeEach(() => {
33
+ promptCallbacks = [];
34
+ initialize = vi.fn();
35
+ prompt = vi.fn((callback?: PromptCallback) => {
36
+ if (callback) {
37
+ promptCallbacks.push(callback);
38
+ }
39
+ });
40
+ revoke = vi.fn();
41
+
42
+ const googleMock = {
43
+ accounts: {
44
+ id: {
45
+ initialize,
46
+ prompt,
47
+ revoke,
48
+ },
49
+ },
50
+ };
51
+
52
+ (globalThis as typeof globalThis & { google: typeof google }).google = googleMock as unknown as typeof google;
53
+
54
+ const storage = new Map<string, string>();
55
+ const localStorageMock: Storage = {
56
+ get length() {
57
+ return storage.size;
58
+ },
59
+ clear() {
60
+ storage.clear();
61
+ },
62
+ getItem(key: string) {
63
+ return storage.get(key) ?? null;
64
+ },
65
+ key(index: number) {
66
+ return Array.from(storage.keys())[index] ?? null;
67
+ },
68
+ removeItem(key: string) {
69
+ storage.delete(key);
70
+ },
71
+ setItem(key: string, value: string) {
72
+ storage.set(key, String(value));
73
+ },
74
+ };
75
+ (globalThis as typeof globalThis & { localStorage: Storage }).localStorage = localStorageMock;
76
+ });
77
+
78
+ afterEach(() => {
79
+ delete (globalThis as typeof globalThis & { google?: typeof google }).google;
80
+ delete (globalThis as typeof globalThis & { localStorage?: Storage }).localStorage;
81
+ promptCallbacks = [];
82
+ vi.clearAllMocks();
83
+ });
84
+
85
+ it('在提示被关闭后重置初始化状态,并允许再次唤起', async () => {
86
+ const events: boolean[] = [];
87
+ const auth = new AwesomeAuth({ googleId: 'test-client' });
88
+ auth.on(AwesomeAuthEvent.INIT, (value: boolean) => {
89
+ events.push(value);
90
+ });
91
+
92
+ await flushPromises();
93
+ expect(promptCallbacks).toHaveLength(1);
94
+ promptCallbacks[0](createPromptNotification('dismissed'));
95
+
96
+ expect(events).toEqual([false]);
97
+
98
+ auth.doSignIn();
99
+ await flushPromises();
100
+ expect(promptCallbacks).toHaveLength(2);
101
+ expect(events[1]).toBe(true);
102
+ expect(initialize).toHaveBeenCalledTimes(1);
103
+ });
104
+
105
+ it('在提示未显示时结束初始化状态', async () => {
106
+ const events: boolean[] = [];
107
+ const auth = new AwesomeAuth({ googleId: 'test-client' });
108
+ auth.on(AwesomeAuthEvent.INIT, (value: boolean) => {
109
+ events.push(value);
110
+ });
111
+
112
+ await flushPromises();
113
+ expect(promptCallbacks).toHaveLength(1);
114
+ promptCallbacks[0](createPromptNotification('not-displayed'));
115
+
116
+ expect(events).toEqual([false]);
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
+ });
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"],"version":"5.6.3"}
1
+ {"root":["./src/auth.ts","./src/main.ts","./src/vite-env.d.ts","./src/app.vue"],"version":"5.9.3"}
@@ -1 +1 @@
1
- {"root":["./vite.config.ts"],"version":"5.6.3"}
1
+ {"root":["./vite.config.ts"],"version":"5.9.3"}
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: 'happy-dom',
6
+ include: ['tests/**/*.test.ts'],
7
+ globals: false,
8
+ },
9
+ });