@roudanio/awesome-auth 0.1.0
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/.env +3 -0
- package/LICENSE.md +7 -0
- package/README.md +101 -0
- package/dist/auth.d.ts +39 -0
- package/dist/awesome-auth.iife.js +1 -0
- package/dist/awesome-auth.js +350 -0
- package/dist/awesome-auth.umd.js +1 -0
- package/package.json +37 -0
- package/tsconfig.app.tsbuildinfo +1 -0
- package/tsconfig.node.tsbuildinfo +1 -0
package/.env
ADDED
package/LICENSE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2024 @meathill
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Awesome Auth
|
|
2
|
+
========
|
|
3
|
+
|
|
4
|
+
Awesome Auth is mainly used by static sites to give users functionalities
|
|
5
|
+
like comment, like, validation, etc. It could be used with Awesome Comment,
|
|
6
|
+
or alternative with Auth0.
|
|
7
|
+
|
|
8
|
+
We assume that you, as a static site owner, don't need a complex user system.
|
|
9
|
+
The only thing you need is to know who is this current user, and allow them
|
|
10
|
+
or disallow them to do something. You don't need to store sensitive data,
|
|
11
|
+
just some useful information like game scores to make user more engaged.
|
|
12
|
+
|
|
13
|
+
So, here are something we will provide:
|
|
14
|
+
|
|
15
|
+
- Only SSO via Google Identity (other providers will be added soon)
|
|
16
|
+
- Serverless / Worker based backend API, only for validation
|
|
17
|
+
- No user data stored
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
Usage
|
|
21
|
+
--------
|
|
22
|
+
|
|
23
|
+
1. Deploy the backend API
|
|
24
|
+
1. Fork this repo
|
|
25
|
+
2. Deploy `/auth-admin` on Serverless / Self-hosted servers
|
|
26
|
+
3. Set up the environment variables
|
|
27
|
+
2. Integrate Awesome Auth into your site
|
|
28
|
+
```js
|
|
29
|
+
import { getInstance } from '@roudanio/awesome-auth';
|
|
30
|
+
|
|
31
|
+
const auth = getInstance({
|
|
32
|
+
googleId: 'YOUR-GOOGLE-CLIENT-ID',
|
|
33
|
+
root: 'https://your-backend-api.com',
|
|
34
|
+
});
|
|
35
|
+
// register events to handle user state
|
|
36
|
+
awesomeAuth.on(AwesomeAuthEvent.VERIFIED, handleVerified);
|
|
37
|
+
awesomeAuth.on(AwesomeAuthEvent.VERIFYING, handleUnverified);
|
|
38
|
+
```
|
|
39
|
+
3. Add your own code for your own features
|
|
40
|
+
```js
|
|
41
|
+
// in your frontend code, attach access token to requests
|
|
42
|
+
const token = auth.accessToken;
|
|
43
|
+
fetch('https://your-backend-api.com/your-endpoint', {
|
|
44
|
+
headers: {
|
|
45
|
+
Authorization: `Bearer ${token}`,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// in your backend API, validate the token by JWT.verify or with http request
|
|
50
|
+
const token = getHeader('Authorization');
|
|
51
|
+
const user = jwt.verify(token, process.env.JWT_SECRET);
|
|
52
|
+
if (!user) {
|
|
53
|
+
// not valid user, return 401 or something else
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Store or retrieve user data
|
|
59
|
+
|
|
60
|
+
After all setup, you can store or retrieve user data like this:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
// store
|
|
64
|
+
auth.store(key, value);
|
|
65
|
+
|
|
66
|
+
// retrieve
|
|
67
|
+
auth.retrieve(key);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### with Awesome Comment
|
|
71
|
+
|
|
72
|
+
Of course it's very simple to use Awesome Auth with Awesome Comment:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
import { getInstance } from '@roudanio/awesome-auth';
|
|
76
|
+
|
|
77
|
+
const auth = getInstance({
|
|
78
|
+
googleId: 'YOUR-GOOGLE-CLIENT-ID',
|
|
79
|
+
root: 'https://your-backend-api.com',
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
AwesomeComment.init({
|
|
83
|
+
awesomeAuth: auth,
|
|
84
|
+
// other options
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
Support SSO
|
|
90
|
+
------
|
|
91
|
+
|
|
92
|
+
- [x] Google Identity
|
|
93
|
+
- [ ] GitHub SSO
|
|
94
|
+
- [ ] Sign in with Apple
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
LICENSE
|
|
98
|
+
------
|
|
99
|
+
|
|
100
|
+
[MIT](./LICENSE.md)
|
|
101
|
+
```
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { default as EventEmitter3 } from 'eventemitter3';
|
|
2
|
+
import { JwtPayload } from 'jwt-decode';
|
|
3
|
+
export interface AwesomeAuthProps {
|
|
4
|
+
googleId: string;
|
|
5
|
+
prefix?: string;
|
|
6
|
+
root?: string;
|
|
7
|
+
}
|
|
8
|
+
declare global {
|
|
9
|
+
function onGoogleLibraryLoad(): void;
|
|
10
|
+
}
|
|
11
|
+
export declare enum AwesomeAuthEvent {
|
|
12
|
+
INIT = "init",
|
|
13
|
+
VERIFYING = "verifying",
|
|
14
|
+
VERIFIED = "verified",
|
|
15
|
+
REFRESH = "refresh",
|
|
16
|
+
ERROR = "error"
|
|
17
|
+
}
|
|
18
|
+
export declare class AwesomeAuth extends EventEmitter3 {
|
|
19
|
+
#private;
|
|
20
|
+
constructor({ googleId, prefix, root, }: AwesomeAuthProps);
|
|
21
|
+
get accessToken(): string;
|
|
22
|
+
get expiredIn(): number;
|
|
23
|
+
get isVerifying(): boolean;
|
|
24
|
+
get isVerified(): boolean;
|
|
25
|
+
get localKey(): string;
|
|
26
|
+
get root(): string;
|
|
27
|
+
get user(): JwtPayload;
|
|
28
|
+
doSignIn(): void;
|
|
29
|
+
doSignOut(): void;
|
|
30
|
+
store(key: string, value: unknown): Promise<void>;
|
|
31
|
+
retrieve(key: string): Promise<unknown>;
|
|
32
|
+
private initGoogleIdentity;
|
|
33
|
+
private refreshCountDown;
|
|
34
|
+
private refreshToken;
|
|
35
|
+
private setAccessToken;
|
|
36
|
+
private verifyToken;
|
|
37
|
+
private onGoogleIdentityCallback;
|
|
38
|
+
}
|
|
39
|
+
export declare function getInstance(params: AwesomeAuthProps): AwesomeAuth;
|
|
@@ -0,0 +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 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 re=n.length,T;for(f=0;f<re;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})(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,(r,t)=>{let a=t.charCodeAt(0).toString(16).toUpperCase();return a.length<2&&(a="0"+a),"%"+a}))}function N(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 L(r)}catch{return atob(r)}}function D(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=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 r=z.call(e,S),t=e[S];try{e[S]=void 0;var a=!0}catch{}var d=J.call(e);return a&&(r?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;#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=Z(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)){ee(),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(_),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=D(r)}catch{this.#t={}}this.#s=this.#t.exp||0,this.expiredIn>0&&(clearInterval(_),_=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 ee(){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 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}({});
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
function E(e) {
|
|
2
|
+
return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
|
|
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), f = t ? t + i : i;
|
|
17
|
+
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;
|
|
18
|
+
}
|
|
19
|
+
function T(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, f = new Array(u); p < u; p++)
|
|
36
|
+
f[p] = o[p].fn;
|
|
37
|
+
return f;
|
|
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, f) {
|
|
42
|
+
var g = t ? t + i : i;
|
|
43
|
+
if (!this._events[g]) return !1;
|
|
44
|
+
var n = this._events[g], y = arguments.length, b, l;
|
|
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, f), !0;
|
|
59
|
+
}
|
|
60
|
+
for (l = 1, b = new Array(y - 1); l < y; l++)
|
|
61
|
+
b[l - 1] = arguments[l];
|
|
62
|
+
n.fn.apply(n.context, b);
|
|
63
|
+
} else {
|
|
64
|
+
var C = n.length, m;
|
|
65
|
+
for (l = 0; l < C; l++)
|
|
66
|
+
switch (n[l].once && this.removeListener(i, n[l].fn, void 0, !0), y) {
|
|
67
|
+
case 1:
|
|
68
|
+
n[l].fn.call(n[l].context);
|
|
69
|
+
break;
|
|
70
|
+
case 2:
|
|
71
|
+
n[l].fn.call(n[l].context, s);
|
|
72
|
+
break;
|
|
73
|
+
case 3:
|
|
74
|
+
n[l].fn.call(n[l].context, s, o);
|
|
75
|
+
break;
|
|
76
|
+
case 4:
|
|
77
|
+
n[l].fn.call(n[l].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[l].fn.apply(n[l].context, b);
|
|
83
|
+
}
|
|
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 T(this, u), this;
|
|
95
|
+
var f = this._events[u];
|
|
96
|
+
if (f.fn)
|
|
97
|
+
f.fn === s && (!p || f.once) && (!o || f.context === o) && T(this, u);
|
|
98
|
+
else {
|
|
99
|
+
for (var g = 0, n = [], y = f.length; g < y; g++)
|
|
100
|
+
(f[g].fn !== s || p && !f[g].once || o && f[g].context !== o) && n.push(f[g]);
|
|
101
|
+
n.length ? this._events[u] = n.length === 1 ? n[0] : n : T(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] && T(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($);
|
|
111
|
+
class S extends Error {
|
|
112
|
+
}
|
|
113
|
+
S.prototype.name = "InvalidTokenError";
|
|
114
|
+
function A(e) {
|
|
115
|
+
return decodeURIComponent(atob(e).replace(/(.)/g, (r, t) => {
|
|
116
|
+
let a = t.charCodeAt(0).toString(16).toUpperCase();
|
|
117
|
+
return a.length < 2 && (a = "0" + a), "%" + a;
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
function G(e) {
|
|
121
|
+
let r = e.replace(/-/g, "+").replace(/_/g, "/");
|
|
122
|
+
switch (r.length % 4) {
|
|
123
|
+
case 0:
|
|
124
|
+
break;
|
|
125
|
+
case 2:
|
|
126
|
+
r += "==";
|
|
127
|
+
break;
|
|
128
|
+
case 3:
|
|
129
|
+
r += "=";
|
|
130
|
+
break;
|
|
131
|
+
default:
|
|
132
|
+
throw new Error("base64 string is not of the correct length");
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
return A(r);
|
|
136
|
+
} catch {
|
|
137
|
+
return atob(r);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function L(e, r) {
|
|
141
|
+
if (typeof e != "string")
|
|
142
|
+
throw new S("Invalid token specified: must be a string");
|
|
143
|
+
r || (r = {});
|
|
144
|
+
const t = r.header === !0 ? 0 : 1, a = e.split(".")[t];
|
|
145
|
+
if (typeof a != "string")
|
|
146
|
+
throw new S(`Invalid token specified: missing part #${t + 1}`);
|
|
147
|
+
let d;
|
|
148
|
+
try {
|
|
149
|
+
d = G(a);
|
|
150
|
+
} catch (v) {
|
|
151
|
+
throw new S(`Invalid token specified: invalid base64 for part #${t + 1} (${v.message})`);
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
return JSON.parse(d);
|
|
155
|
+
} catch (v) {
|
|
156
|
+
throw new S(`Invalid token specified: invalid json for part #${t + 1} (${v.message})`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
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];
|
|
162
|
+
try {
|
|
163
|
+
e[w] = void 0;
|
|
164
|
+
var a = !0;
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
var d = V.call(e);
|
|
168
|
+
return a && (r ? e[w] = t : delete e[w]), d;
|
|
169
|
+
}
|
|
170
|
+
var J = Object.prototype, U = J.toString;
|
|
171
|
+
function B(e) {
|
|
172
|
+
return U.call(e);
|
|
173
|
+
}
|
|
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);
|
|
177
|
+
}
|
|
178
|
+
var M = Array.isArray;
|
|
179
|
+
function Y(e) {
|
|
180
|
+
return e != null && typeof e == "object";
|
|
181
|
+
}
|
|
182
|
+
var Q = "[object String]";
|
|
183
|
+
function W(e) {
|
|
184
|
+
return typeof e == "string" || !M(e) && Y(e) && H(e) == Q;
|
|
185
|
+
}
|
|
186
|
+
var X = /* @__PURE__ */ ((e) => (e.INIT = "init", e.VERIFYING = "verifying", e.VERIFIED = "verified", e.REFRESH = "refresh", e.ERROR = "error", e))(X || {});
|
|
187
|
+
let _;
|
|
188
|
+
class Z extends P {
|
|
189
|
+
#e = "";
|
|
190
|
+
#t = {};
|
|
191
|
+
#s = 0;
|
|
192
|
+
#c;
|
|
193
|
+
#o = !1;
|
|
194
|
+
#n = !1;
|
|
195
|
+
#i = !1;
|
|
196
|
+
#a;
|
|
197
|
+
#f;
|
|
198
|
+
#r;
|
|
199
|
+
constructor({
|
|
200
|
+
googleId: r,
|
|
201
|
+
prefix: t = "aAuth",
|
|
202
|
+
root: a = "/api"
|
|
203
|
+
}) {
|
|
204
|
+
if (super(), this.#c = r, this.#f = 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();
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
this.initGoogleIdentity();
|
|
211
|
+
}
|
|
212
|
+
get accessToken() {
|
|
213
|
+
return this.#e;
|
|
214
|
+
}
|
|
215
|
+
get expiredIn() {
|
|
216
|
+
return this.#s ? 0 : this.#s - this.#a;
|
|
217
|
+
}
|
|
218
|
+
get isVerifying() {
|
|
219
|
+
return this.#n;
|
|
220
|
+
}
|
|
221
|
+
get isVerified() {
|
|
222
|
+
return this.#i;
|
|
223
|
+
}
|
|
224
|
+
get localKey() {
|
|
225
|
+
return `${this.#f}-token`;
|
|
226
|
+
}
|
|
227
|
+
get root() {
|
|
228
|
+
return this.#r;
|
|
229
|
+
}
|
|
230
|
+
get user() {
|
|
231
|
+
return this.#t;
|
|
232
|
+
}
|
|
233
|
+
doSignIn() {
|
|
234
|
+
this.initGoogleIdentity();
|
|
235
|
+
}
|
|
236
|
+
doSignOut() {
|
|
237
|
+
this.#e = "", google.accounts.id.revoke(this.#t.sub || ""), this.#t = {};
|
|
238
|
+
}
|
|
239
|
+
async store(r, t) {
|
|
240
|
+
t = W(t) ? t : JSON.stringify(t), await fetch(`${this.#r}/store`, {
|
|
241
|
+
method: "POST",
|
|
242
|
+
headers: {
|
|
243
|
+
"Content-type": "application/json",
|
|
244
|
+
Authorization: `Bearer ${this.#e}`
|
|
245
|
+
},
|
|
246
|
+
body: JSON.stringify({
|
|
247
|
+
key: r,
|
|
248
|
+
value: t
|
|
249
|
+
})
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
async retrieve(r) {
|
|
253
|
+
const t = await fetch(`${this.#r}/retrieve`, {
|
|
254
|
+
method: "POST",
|
|
255
|
+
headers: {
|
|
256
|
+
"Content-type": "application/json",
|
|
257
|
+
Authorization: `Bearer ${this.#e}`
|
|
258
|
+
},
|
|
259
|
+
body: JSON.stringify({
|
|
260
|
+
key: r
|
|
261
|
+
})
|
|
262
|
+
}), { data: a } = await t.json();
|
|
263
|
+
return a?.value;
|
|
264
|
+
}
|
|
265
|
+
initGoogleIdentity() {
|
|
266
|
+
if (!("google" in globalThis)) {
|
|
267
|
+
ee(), globalThis.onGoogleLibraryLoad = () => this.initGoogleIdentity();
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.#o || (this.emit("init", !0), this.#o = !0, google.accounts.id.initialize({
|
|
271
|
+
client_id: this.#c,
|
|
272
|
+
callback: (r) => this.onGoogleIdentityCallback(r),
|
|
273
|
+
auto_select: !0,
|
|
274
|
+
ux_mode: "popup"
|
|
275
|
+
}), google.accounts.id.prompt());
|
|
276
|
+
}
|
|
277
|
+
refreshCountDown() {
|
|
278
|
+
this.#a = Date.now() / 1e3 >> 0, this.expiredIn <= 60 && (clearInterval(_), this.refreshToken());
|
|
279
|
+
}
|
|
280
|
+
async refreshToken() {
|
|
281
|
+
this.emit("refresh", !0);
|
|
282
|
+
const r = await fetch(`${this.#r}/refresh-token`, {
|
|
283
|
+
method: "POST",
|
|
284
|
+
headers: {
|
|
285
|
+
"Content-type": "application/json",
|
|
286
|
+
Authorization: `Bearer ${this.#e}`
|
|
287
|
+
}
|
|
288
|
+
}), { data: t } = await r.json(), { token: a } = t;
|
|
289
|
+
this.setAccessToken(a), this.emit("refresh", !1);
|
|
290
|
+
}
|
|
291
|
+
setAccessToken(r, t = !0) {
|
|
292
|
+
if (this.#e = r, t && localStorage.setItem(this.localKey, r), !r) {
|
|
293
|
+
this.#t = {}, this.#s = 0;
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
this.#t = L(r);
|
|
298
|
+
} catch {
|
|
299
|
+
this.#t = {};
|
|
300
|
+
}
|
|
301
|
+
this.#s = this.#t.exp || 0, this.expiredIn > 0 && (clearInterval(_), _ = setInterval(() => this.refreshCountDown(), 1e3));
|
|
302
|
+
}
|
|
303
|
+
async verifyToken() {
|
|
304
|
+
this.emit("verifying", !0), this.#n = !0;
|
|
305
|
+
try {
|
|
306
|
+
const r = await fetch(`${this.#r}/verify-auth`, {
|
|
307
|
+
method: "POST",
|
|
308
|
+
headers: {
|
|
309
|
+
"Content-type": "application/json",
|
|
310
|
+
Authorization: `Bearer ${this.#e}`
|
|
311
|
+
}
|
|
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));
|
|
316
|
+
}
|
|
317
|
+
return this.emit("verifying", !1), this.#n = !1, this.#i;
|
|
318
|
+
}
|
|
319
|
+
async onGoogleIdentityCallback(r) {
|
|
320
|
+
this.emit("init", !1), this.#o = !1, this.emit("verifying", !0), this.#n = !0;
|
|
321
|
+
const t = await fetch(`${this.#r}/google-auth`, {
|
|
322
|
+
method: "POST",
|
|
323
|
+
headers: {
|
|
324
|
+
"Content-type": "application/json"
|
|
325
|
+
},
|
|
326
|
+
body: JSON.stringify({
|
|
327
|
+
credential: r.credential
|
|
328
|
+
})
|
|
329
|
+
}), { data: a } = await t.json();
|
|
330
|
+
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;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
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);
|
|
341
|
+
}
|
|
342
|
+
let I;
|
|
343
|
+
function te(e) {
|
|
344
|
+
return I = I || new Z(e), I;
|
|
345
|
+
}
|
|
346
|
+
export {
|
|
347
|
+
Z as AwesomeAuth,
|
|
348
|
+
X as AwesomeAuthEvent,
|
|
349
|
+
te as getInstance
|
|
350
|
+
};
|
|
@@ -0,0 +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)){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"})});
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@roudanio/awesome-auth",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/awesome-auth.umd.js",
|
|
6
|
+
"module": "dist/awesome-auth.js",
|
|
7
|
+
"browser": "dist/awesome-auth.iife.ts",
|
|
8
|
+
"types": "dist/auth.d.ts",
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"eventemitter3": "^5.0.1",
|
|
11
|
+
"google-auth-library": "^9.14.1",
|
|
12
|
+
"jsonwebtoken": "^9.0.2",
|
|
13
|
+
"jwt-decode": "^4.0.0",
|
|
14
|
+
"lodash-es": "^4.17.21",
|
|
15
|
+
"vue": "^3.5.10",
|
|
16
|
+
"@awesome-comment/core": "0.1.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/gapi": "^0.0.47",
|
|
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.13",
|
|
27
|
+
"typescript": "^5.5.3",
|
|
28
|
+
"vite": "^5.4.8",
|
|
29
|
+
"vite-plugin-dts": "^4.2.3",
|
|
30
|
+
"vue-tsc": "^2.1.6"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"dev": "vite",
|
|
34
|
+
"build": "vue-tsc -b && vite build",
|
|
35
|
+
"preview": "vite preview"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/auth.ts","./src/main.ts","./src/vite-env.d.ts","./src/app.vue"],"version":"5.6.2"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./vite.config.ts"],"version":"5.6.2"}
|