257 lines
7.3 KiB
TypeScript
257 lines
7.3 KiB
TypeScript
import * as plugins from '../plugins.js';
|
|
|
|
import {
|
|
customElement,
|
|
DeesElement,
|
|
property,
|
|
html,
|
|
type TemplateResult,
|
|
css,
|
|
cssManager,
|
|
state,
|
|
domtools,
|
|
} from '@design.estate/dees-element';
|
|
|
|
// third party catalogs
|
|
import '@uptime.link/webwidget';
|
|
|
|
import '@design.estate/dees-catalog';
|
|
import { DeesForm, DeesFormSubmit, DeesInputText } from '@design.estate/dees-catalog';
|
|
import { IdpState } from '../states/idp.state.js';
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
'idp-loginprompt': IdpLoginPrompt;
|
|
}
|
|
}
|
|
|
|
@customElement('idp-loginprompt')
|
|
export class IdpLoginPrompt extends DeesElement {
|
|
public static demo = () => html`<idp-loginprompt></idp-loginprompt>`;
|
|
|
|
@property()
|
|
accessor productOfInterest: string;
|
|
|
|
@property()
|
|
accessor jwt: string;
|
|
|
|
@property({
|
|
reflect: true,
|
|
type: Object,
|
|
})
|
|
accessor appData: plugins.idpInterfaces.data.IApp;
|
|
|
|
public jwtObserable = new domtools.plugins.smartrx.rxjs.Subject<string>();
|
|
|
|
constructor() {
|
|
super();
|
|
domtools.elementBasic.setup();
|
|
}
|
|
|
|
public static styles = [
|
|
cssManager.defaultStyles,
|
|
css`
|
|
:host {
|
|
--foreground: hsl(0 0% 98%);
|
|
--muted-foreground: hsl(240 5% 64.9%);
|
|
|
|
font-family: 'Geist Sans', -apple-system, BlinkMacSystemFont, sans-serif;
|
|
display: block;
|
|
color: var(--foreground);
|
|
}
|
|
|
|
.form-header {
|
|
margin-bottom: 32px;
|
|
text-align: center;
|
|
}
|
|
|
|
.form-header h2 {
|
|
font-size: 24px;
|
|
font-weight: 600;
|
|
color: var(--foreground);
|
|
margin: 0 0 8px 0;
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.form-header p {
|
|
font-size: 14px;
|
|
color: var(--muted-foreground);
|
|
margin: 0;
|
|
}
|
|
|
|
dees-form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
}
|
|
|
|
.form-footer {
|
|
margin-top: 24px;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
color: var(--muted-foreground);
|
|
}
|
|
|
|
.form-footer a {
|
|
color: var(--foreground);
|
|
text-decoration: none;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: opacity 0.15s ease;
|
|
}
|
|
|
|
.form-footer a:hover {
|
|
opacity: 0.8;
|
|
}
|
|
`,
|
|
];
|
|
|
|
public render(): TemplateResult {
|
|
return html`
|
|
<idp-centercontainer>
|
|
<div class="form-header">
|
|
<h2>Sign in to your account</h2>
|
|
<p>Enter your credentials to continue</p>
|
|
</div>
|
|
<dees-form
|
|
id="loginForm"
|
|
@formData="${(eventArg) => {
|
|
this.login({
|
|
emailAddress: eventArg.detail.data.emailAddress,
|
|
passwordArg: eventArg.detail.data.password,
|
|
});
|
|
}}"
|
|
>
|
|
<dees-input-text
|
|
id="loginEmailInput"
|
|
.required=${true}
|
|
key="emailAddress"
|
|
label="Email or Username"
|
|
></dees-input-text>
|
|
<dees-input-text
|
|
.id=${'loginPasswordInput'}
|
|
.key=${'password'}
|
|
.label=${'Password'}
|
|
.isPasswordBool=${true}
|
|
></dees-input-text>
|
|
<dees-form-submit id="loginSubmitButton"></dees-form-submit>
|
|
</dees-form>
|
|
<div class="form-footer">
|
|
Don't have an account? <a @click=${async () => {
|
|
const idpState = await IdpState.getSingletonInstance();
|
|
idpState.domtools.router.pushUrl('/register');
|
|
}}>Create one</a>
|
|
</div>
|
|
</idp-centercontainer>
|
|
`;
|
|
}
|
|
|
|
public async firstUpdated() {
|
|
const domtoolsInstance = await this.domtoolsPromise;
|
|
const loginForm: DeesForm = this.shadowRoot.querySelector('#loginForm');
|
|
const loginPasswordInput: DeesInputText = loginForm.querySelector('#loginPasswordInput');
|
|
const loginSubmitButton: DeesFormSubmit = loginForm.querySelector('#loginSubmitButton');
|
|
const setButtonText = async () => {
|
|
if (loginPasswordInput.value) {
|
|
console.log('updating text of loginprompt.');
|
|
loginSubmitButton.text = 'Login';
|
|
} else {
|
|
loginSubmitButton.text = 'Send magic link (or enter password)';
|
|
}
|
|
};
|
|
loginForm.changeSubject.subscribe(() => {
|
|
console.log(`checking button text ${loginPasswordInput.value}`);
|
|
setButtonText();
|
|
});
|
|
setButtonText();
|
|
}
|
|
|
|
private login = async (valueArg: { emailAddress: string; passwordArg: string }) => {
|
|
// lets disable the submit button
|
|
const loginSubmitButton: plugins.deesCatalog.DeesFormSubmit = this.shadowRoot.querySelector('#loginSubmitButton');
|
|
loginSubmitButton.disabled = true;
|
|
// lets define the needed requests
|
|
const idpState = await IdpState.getSingletonInstance();
|
|
const loginForm: DeesForm = this.shadowRoot.querySelector('#loginForm');
|
|
const loginRequestWithUsernameAndPassword =
|
|
idpState.idpClient.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_LoginWithEmailOrUsernameAndPassword>(
|
|
'loginWithEmailOrUsernameAndPassword'
|
|
);
|
|
const loginRequestWithEmail =
|
|
idpState.idpClient.typedsocket.createTypedRequest<plugins.idpInterfaces.request.IReq_LoginWithEmail>(
|
|
'loginWithEmail'
|
|
);
|
|
|
|
// lets do the actual logging in
|
|
if (valueArg.emailAddress && valueArg.passwordArg) {
|
|
loginForm.setStatus('pending', 'logging in...');
|
|
const response = await loginRequestWithUsernameAndPassword
|
|
.fire({
|
|
username: valueArg.emailAddress, // TODO: rename to emailAddress
|
|
password: valueArg.passwordArg,
|
|
})
|
|
.catch(() => {
|
|
loginForm.setStatus('error', 'could not log you in. Try Again!');
|
|
return;
|
|
});
|
|
if (!response) {
|
|
return;
|
|
}
|
|
if (response.refreshToken) {
|
|
loginForm.setStatus('pending', 'obtained refreshToken...');
|
|
const jwt = await idpState.idpClient.refreshJwt(response.refreshToken);
|
|
if (jwt) {
|
|
loginForm.setStatus('success', 'obtained jwt.');
|
|
idpState.domtools.router.pushUrl('/account');
|
|
} else {
|
|
loginForm.setStatus('error', 'something went wrong');
|
|
}
|
|
} else {
|
|
}
|
|
} else if (valueArg.emailAddress && !valueArg.passwordArg) {
|
|
loginForm.setStatus('pending', 'sending magic link...');
|
|
const response = await loginRequestWithEmail.fire({
|
|
email: valueArg.emailAddress,
|
|
});
|
|
if (response.status === 'ok') {
|
|
loginForm.setStatus('success', 'Please check your email!');
|
|
}
|
|
console.log(response);
|
|
}
|
|
};
|
|
|
|
public async dispatchJwt(jwtArg?: string) {
|
|
if (jwtArg !== undefined) {
|
|
console.log(`dispatching jwt from loginprompt.`);
|
|
this.jwt = jwtArg;
|
|
await domtools.plugins.smartdelay.delayFor(200);
|
|
this.dispatchEvent(
|
|
new CustomEvent('leleLoginGotJwt', {
|
|
detail: {
|
|
jwt: this.jwt,
|
|
},
|
|
})
|
|
);
|
|
this.jwtObserable.next(this.jwt);
|
|
}
|
|
}
|
|
|
|
public async focus() {
|
|
(
|
|
this.shadowRoot.querySelector('#loginEmailInput') as plugins.deesCatalog.DeesInputText
|
|
).focus();
|
|
}
|
|
|
|
public async show() {
|
|
await this.updateComplete;
|
|
const centerContainer = this.shadowRoot.querySelector('idp-centercontainer');
|
|
await centerContainer.show();
|
|
}
|
|
|
|
public async hide() {
|
|
await this.updateComplete;
|
|
const centerContainer = this.shadowRoot.querySelector('idp-centercontainer');
|
|
await centerContainer.hide();
|
|
}
|
|
}
|