151 lines
5.3 KiB
JavaScript
151 lines
5.3 KiB
JavaScript
|
#include loading.jsx
|
||
|
#include app/info.jsx
|
||
|
#include app/scope.jsx
|
||
|
#include header/header.js
|
||
|
#include header/user.jsx
|
||
|
|
||
|
const HanyuuOAuth2DeviceVerify = () => {
|
||
|
const queryParams = new URLSearchParams(window.location.search);
|
||
|
const loading = new HanyuuOAuth2Loading('.js-loading');
|
||
|
const header = new HanyuuOAuth2Header;
|
||
|
|
||
|
const fAuths = document.querySelector('.js-verify-authorise');
|
||
|
const eAuthsInfo = document.querySelector('.js-verify-authorise-info');
|
||
|
const eAuthsScope = document.querySelector('.js-verify-authorise-scope');
|
||
|
|
||
|
const rApproved = document.querySelector('.js-verify-approved');
|
||
|
const rDenied = document.querySelector('.js-verify-denied');
|
||
|
|
||
|
let userCode = '';
|
||
|
let userHeader;
|
||
|
const verifyDeviceRequest = async approve => {
|
||
|
return await $x.post('/oauth2/device/verify', { type: 'json' }, {
|
||
|
_csrfp: HanyuuCSRFP.getToken(),
|
||
|
code: userCode,
|
||
|
approve: approve === true ? 'yes' : 'no',
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const handleVerifyDeviceResponse = result => {
|
||
|
const response = result.body();
|
||
|
|
||
|
if(!response || typeof response.error === 'string') {
|
||
|
// TODO: nicer errors
|
||
|
if(response.error === 'auth')
|
||
|
alert('You are not logged in.');
|
||
|
else if(response.error === 'csrf')
|
||
|
alert('Request verification failed, please refresh and try again.');
|
||
|
else if(response.error === 'code')
|
||
|
alert('This code is not associated with any device authorisation request.');
|
||
|
else if(response.error === 'approval')
|
||
|
alert('The device authorisation request associated with this code is not pending approval.');
|
||
|
else if(response.error === 'invalid')
|
||
|
alert('Invalid approval state specified.');
|
||
|
else
|
||
|
alert(`An unknown error occurred: ${response.error}`);
|
||
|
|
||
|
loading.visible = false;
|
||
|
fAuths.classList.remove('hidden');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
loading.visible = false;
|
||
|
if(response.approval === 'approved')
|
||
|
rApproved.classList.remove('hidden');
|
||
|
else
|
||
|
rDenied.classList.remove('hidden');
|
||
|
};
|
||
|
|
||
|
fAuths.onsubmit = ev => {
|
||
|
ev.preventDefault();
|
||
|
|
||
|
loading.visible = true;
|
||
|
fAuths.classList.add('hidden');
|
||
|
|
||
|
if(userHeader)
|
||
|
userHeader.guiseVisible = false;
|
||
|
|
||
|
verifyDeviceRequest(ev.submitter.value === 'yes')
|
||
|
.then(handleVerifyDeviceResponse);
|
||
|
};
|
||
|
|
||
|
const fCode = document.querySelector('.js-verify-code');
|
||
|
const eUserCode = fCode.elements.namedItem('code');
|
||
|
|
||
|
fCode.onsubmit = ev => {
|
||
|
ev.preventDefault();
|
||
|
|
||
|
loading.visible = true;
|
||
|
fCode.classList.add('hidden');
|
||
|
|
||
|
$x.get(`/oauth2/device/resolve?csrfp=${encodeURIComponent(HanyuuCSRFP.getToken())}&code=${encodeURIComponent(eUserCode.value)}`, { type: 'json' })
|
||
|
.then(result => {
|
||
|
const response = result.body();
|
||
|
|
||
|
if(!response || typeof response.error === 'string') {
|
||
|
// TODO: nicer errors
|
||
|
if(response.error === 'auth')
|
||
|
alert('You are not logged in.');
|
||
|
else if(response.error === 'csrf')
|
||
|
alert('Request verification failed, please refresh and try again.');
|
||
|
else if(response.error === 'code')
|
||
|
alert('This code is not associated with any device authorisation request.');
|
||
|
else if(response.error === 'approval')
|
||
|
alert('The device authorisation request associated with this code is not pending approval.');
|
||
|
else
|
||
|
alert(`An unknown error occurred: ${response.error}`);
|
||
|
|
||
|
loading.visible = false;
|
||
|
fCode.classList.remove('hidden');
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
userCode = response.device.code;
|
||
|
|
||
|
userHeader = new HanyuuOAuth2UserHeader(response.user);
|
||
|
header.setElement(userHeader);
|
||
|
|
||
|
if(response.app.trusted && response.user.guise === undefined) {
|
||
|
if(userHeader)
|
||
|
userHeader.guiseVisible = false;
|
||
|
|
||
|
verifyDeviceRequest(true).then(handleVerifyDeviceResponse);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const appElem = new HanyuuOAuth2AppInfo(response.app);
|
||
|
eAuthsInfo.replaceWith(appElem.element);
|
||
|
|
||
|
const scopeElem = new HanyuuOAuth2AppScopeList();
|
||
|
eAuthsScope.replaceWith(scopeElem.element);
|
||
|
|
||
|
loading.visible = false;
|
||
|
fAuths.classList.remove('hidden');
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const validateCodeInput = () => {
|
||
|
// [A-Za-z0-8]{3}\-[A-Za-z0-8]{3}\-[A-Za-z0-8]{3}
|
||
|
// 0 -> O, 1 -> I, 8 -> B
|
||
|
|
||
|
const eCode = eUserCode.value;
|
||
|
|
||
|
return true;
|
||
|
};
|
||
|
|
||
|
eUserCode.oninput = () => {
|
||
|
validateCodeInput();
|
||
|
console.warn(eUserCode.value);
|
||
|
};
|
||
|
|
||
|
if(queryParams.has('code') && eUserCode.value === '')
|
||
|
eUserCode.value = queryParams.get('code');
|
||
|
|
||
|
if(validateCodeInput()) {
|
||
|
fCode.requestSubmit();
|
||
|
} else {
|
||
|
loading.visible = false;
|
||
|
fCode.classList.remove('hidden');
|
||
|
}
|
||
|
};
|