import "@pwabuilder/pwaauth"; import { Component, ComponentParams, CONFIG, ComponentDoneResponse, Service, logger, Package, _DOMCreateElement, QCObjectsShadowedElement, global } from "qcobjects"; import { Modal, ModalParams, SignalComponent } from "./com.qcobjects.modal.components"; interface AuthData { userAccessToken:string; authenticated:boolean; user: { name:string; email:string; } } class LoginComponent extends SignalComponent { tplsource = "inline"; template = `

Sign In


`; constructor(component:ComponentParams){ super(component); this.processorHandler.setProcessor(this.authConfig); } authConfig (_component:Component, configValue:string):string { const value = configValue.split(".").reduce((a, b)=>{return a[b];}, CONFIG.get("backend", {auth:{}}).auth); return value; } signInCompleted (ev:any) { const signIn = ev.detail; if (signIn.error) { console.error("Sign in failed", signIn.error); } else { console.log("Email: ", signIn.email); console.log("Name: ", signIn.name); console.log("Picture: ", signIn.imageUrl); console.log("Access token", signIn.accessToken); console.log("Access token expiration date", signIn.accessTokenExpiration); console.log("Provider (MS, Google, FB): ", signIn.provider); console.log("Raw data from provider: ", signIn.providerData); global.set("signIn", signIn); this.fireSignal("signInCompleted"); } } done(standardResponse: ComponentDoneResponse): Promise { return new Promise ((resolve)=> { const pwaAuth = _DOMCreateElement("pwa-auth"); pwaAuth.setAttribute("appearance", "none"); pwaAuth.setAttribute("microsoftkey", this.authConfig(this, "microsoftapikey")); pwaAuth.setAttribute("googlekey", this.authConfig(this, "googleapikey")); pwaAuth.setAttribute("credentialmode", "none"); document.body.appendChild(pwaAuth); const signInWithMicrosoftBtn = (this.shadowRoot as QCObjectsShadowedElement).subelements("button.microsoft-btn").pop() as HTMLButtonElement; const signInWithGoogleBtn = (this.shadowRoot as QCObjectsShadowedElement).subelements("button.google-btn").pop() as HTMLButtonElement; signInWithMicrosoftBtn.addEventListener("click", () => (pwaAuth as any).signIn("Microsoft")); signInWithGoogleBtn.addEventListener("click", () => (pwaAuth as any).signIn("Google")); if (pwaAuth){ pwaAuth.addEventListener("signin-completed", this.signInCompleted.bind(this)); } else { throw Error("[AuthComponent][Done] pwa-auth not loaded."); } resolve(super.done(standardResponse)); }); } } class LoginModal extends Modal { constructor(component:ModalParams){ component.enclosureComponentClass = "LoginComponent"; super(component); } } class AuthComponent extends Component { authenticated = false; loginModal!:LoginModal; accessToken!: string; lockedInnerHTML!:string; authServiceInstance!:Service; authBuild (): Promise<{ request: XMLHttpRequest; component: Component; }> { return new Promise ((resolve, reject)=>{ (async ()=>{ try { await this.auth(); if (this.authenticated){ logger.debug("User has been authenticated"); resolve({request:new XMLHttpRequest(), component: this }); } else { await this.login(); resolve({request:new XMLHttpRequest(), component: this }); } } catch (e){ reject(e); } })(); }); } rebuild(): Promise<{ request: XMLHttpRequest; component: Component; }> { return this.authBuild() .finally(()=>{ return super.rebuild(); }); } reset(){ this.body.innerHTML = ""; if (typeof this.shadowRoot !== "undefined"){ this.body.append(this.shadowRoot.host); } } async login(){ logger.debug("LOGIN"); this.loginModal = new LoginModal({name:"login-modal", __parent__:this}); this.loginModal.submodal.on("signInCompleted", ()=>{ this.loginModal.close(); this.authenticated = true; this.reset(); }); this.attachLoginModal(); } attachLoginModal (){ this.body.innerHTML = ""; this.body.append(this.loginModal.body); } getAccessToken():Promise { return new Promise((resolve)=>{ this.authenticated = this.data.authenticated; resolve((this.data as AuthData).userAccessToken); }); } auth ():Promise<{component: AuthComponent; }>{ return new Promise ((resolve)=> { if (CONFIG.get("auth", {enabled:true}).enabled){ logger.debug("LOGIN"); this.getAccessToken() .then((accessToken)=>{ this.accessToken = accessToken; resolve({component:this}); }); } else { this.authenticated = true; resolve({component:this}); } }); } } Package("com.qcobjects.auth.login", [ LoginComponent, LoginModal, AuthComponent ]); export {LoginComponent, LoginModal, AuthComponent};