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};