144 lines
3.9 KiB
HTML
144 lines
3.9 KiB
HTML
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
|
<link rel="import" href='../../bower_components/paper-button/paper-button.html'>
|
|
|
|
<link rel='import' href='../components/ha-form.html'>
|
|
<link rel='import' href='../util/hass-mixins.html'>
|
|
|
|
<dom-module id='ha-auth-flow'>
|
|
<template>
|
|
<template is='dom-if' if='[[_equals(_state, "loading")]]'>
|
|
Please wait
|
|
</template>
|
|
<template is='dom-if' if='[[_equals(_state, "error")]]'>
|
|
Something went wrong
|
|
</template>
|
|
<template is='dom-if' if='[[_equals(_state, "step")]]'>
|
|
<template is='dom-if' if='[[_equals(_step.type, "abort")]]'>
|
|
Aborted
|
|
</template>
|
|
<template is='dom-if' if='[[_equals(_step.type, "create_entry")]]'>
|
|
Success!
|
|
</template>
|
|
<template is='dom-if' if='[[_equals(_step.type, "form")]]'>
|
|
<ha-form
|
|
data='{{_stepData}}'
|
|
schema='[[_step.data_schema]]'
|
|
error='[[_step.errors]]'
|
|
></ha-form>
|
|
</template>
|
|
<paper-button on-click='_handleSubmit'>[[_computeSubmitCaption(_step.type)]]</paper-button>
|
|
</template>
|
|
</template>
|
|
</dom-module>
|
|
|
|
<script>
|
|
/*
|
|
* @appliesMixin window.hassMixins.EventsMixin
|
|
*/
|
|
class HaAuthFlow extends window.hassMixins.EventsMixin(Polymer.Element) {
|
|
static get is() { return 'ha-auth-flow'; }
|
|
static get properties() {
|
|
return {
|
|
authProvider: Object,
|
|
clientId: String,
|
|
clientSecret: String,
|
|
redirectUri: String,
|
|
oauth2State: String,
|
|
_state: {
|
|
type: String,
|
|
value: 'loading'
|
|
},
|
|
_stepData: {
|
|
type: Object,
|
|
value: () => ({}),
|
|
},
|
|
_step: Object,
|
|
};
|
|
}
|
|
connectedCallback() {
|
|
super.connectedCallback();
|
|
|
|
fetch('/auth/login_flow', {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: `Basic ${btoa(`${this.clientId}:${this.clientSecret}`)}`
|
|
},
|
|
body: JSON.stringify({
|
|
handler: [this.authProvider.type, this.authProvider.id],
|
|
redirect_uri: this.redirectUri,
|
|
})
|
|
}).then((response) => {
|
|
if (!response.ok) throw new Error();
|
|
return response.json();
|
|
}).then(step => this.setProperties({
|
|
_step: step,
|
|
_state: 'step',
|
|
})).catch((err) => {
|
|
// eslint-disable-next-line
|
|
console.error('Error starting auth flow', err);
|
|
this._state = 'error';
|
|
});
|
|
}
|
|
|
|
_equals(a, b) {
|
|
return a === b;
|
|
}
|
|
|
|
_computeSubmitCaption(stepType) {
|
|
return stepType === 'form' ? 'Submit' : 'Start over';
|
|
}
|
|
|
|
_handleSubmit() {
|
|
if (this._step.type !== 'form') {
|
|
this.fire('reset');
|
|
return;
|
|
}
|
|
this._state = 'loading';
|
|
|
|
fetch(`/auth/login_flow/${this._step.flow_id}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: `Basic ${btoa(`${this.clientId}:${this.clientSecret}`)}`
|
|
},
|
|
body: JSON.stringify(this._stepData)
|
|
}).then((response) => {
|
|
if (!response.ok) throw new Error();
|
|
return response.json();
|
|
}).then((newStep) => {
|
|
if (newStep.type === 'create_entry') {
|
|
// OAuth 2: 3.1.2 we need to retain query component of a redirect URI
|
|
let url = this.redirectUri;
|
|
if (!url.includes('?')) {
|
|
url += '?';
|
|
} else if (!url.endsWith('&')) {
|
|
url += '&';
|
|
}
|
|
|
|
url += `code=${encodeURIComponent(newStep.result)}`;
|
|
|
|
if (this.oauth2State) {
|
|
url += `&state=${encodeURIComponent(this.oauth2State)}`;
|
|
}
|
|
|
|
document.location = url;
|
|
return;
|
|
}
|
|
|
|
const props = {
|
|
_step: newStep,
|
|
_state: 'step',
|
|
};
|
|
if (newStep.step_id !== this._step.step_id) {
|
|
props._stepData = {};
|
|
}
|
|
this.setProperties(props);
|
|
}).catch((err) => {
|
|
// eslint-disable-next-line
|
|
console.error('Error loading auth providers', err);
|
|
this._state = 'error-loading';
|
|
});
|
|
}
|
|
}
|
|
customElements.define(HaAuthFlow.is, HaAuthFlow);
|
|
</script>
|