All files / src/components/zd-login login-button.ts

100% Statements 29/29
100% Branches 6/6
100% Functions 6/6
100% Lines 29/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 11393x 93x             93x 17x         17x         17x         17x                                     12x 12x 12x 10x 10x 9x     1x               10x 10x               10x 10x 10x 24x   10x               9x 7x 7x             7x 6x 6x     2x                 3x                
import { Config, Cookie, Http, IDictionary, Router } from '@zeedhi/core';
import { Button } from '../zd-button/button';
import { Form } from '../zd-form/form';
import { ILoginButton } from './interfaces';
 
/**
 * The Login button component <code>zd-login-button</code> is used to handle login.
 */
export class LoginButton extends Button implements ILoginButton {
	public parent?: Form = undefined;
 
	/**
	 * Endpoint used to authentication
	 */
	public authUrl = '';
 
	/**
	 * Url to redirect
	 */
	public redirectUrl: string = Config.homeUrl;
 
	/**
	 * Extra params to be added on login request
	 */
	public requestParams: IDictionary<any> = {};
 
	/* istanbul ignore next */
	/**
	 * Create a new LoginButton
	 * @param props LoginButton definition
	 */
	constructor(props: ILoginButton) {
		super(props);
		this.authUrl = Config.env?.authUrl || props.authUrl;
		this.redirectUrl = this.getInitValue('redirectUrl', props.redirectUrl, this.redirectUrl);
		this.requestParams = this.getInitValue('requestParams', props.requestParams, this.requestParams);
		this.createAccessors();
	}
 
	/**
	 * Click event
	 */
	public async click(event: Event, element: any) {
		try {
			const test = await this.parent?.validate();
			if (test?.valid && this.parent) {
				const parentValue = this.parent.value;
				const response = await this.sendRequest(parentValue);
				this.handleLoginSuccess(event, element, response);
			}
		} catch (error) {
			this.handleLoginFail(event, element, error);
		}
	}
 
	/**
	 * Send request to the configured endpoint
	 */
	private async sendRequest(parentValue: IDictionary<any>) {
		const requestHeader: any = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } };
		return Http.post(this.authUrl, this.getQueryString(parentValue), requestHeader);
	}
 
	/**
	 * Returns a parsed query string
	 * @param args Params to the query string
	 */
	private getQueryString(args: IDictionary<any>): string {
		const allParams = { ...this.requestParams, ...args };
		const params = new URLSearchParams();
		Object.keys(allParams).forEach((key) => {
			params.set(key, allParams[key]);
		});
		return params.toString();
	}
 
	/**
	 * Redirect the app to the configured url
	 * @param args Response
	 */
	private handleLoginSuccess(event: Event, element: any, response: any) {
		if (response.status === 200) {
			let preventDefault: boolean | void = false;
			preventDefault = this.callEvent('loginSuccess', {
				element,
				response,
				event,
				component: this,
			});
 
			if (!preventDefault) {
				Cookie.setCookie('token', response.data.token);
				Router.replace(this.redirectUrl);
			}
		} else {
			this.handleLoginFail(event, element, response);
		}
	}
 
	/**
	 * Emit the LoginFail event
	 * @param args Response
	 */
	private handleLoginFail(event: Event, element: any, error: any) {
		this.callEvent('loginFail', {
			element,
			error,
			event,
			component: this,
		});
	}
}