hanyuu/assets/oauth2.js/verify.js
flashwave 5fa03dd551 Removed mentions of "device" from the UI and URLs.
While the intention of the extension specification to OAuth2 for device codes is indeed intended for handling authorisation on devices where the user cannot use any input method on the device,
 it's also very useful for when we want to authorise older devices where there are other difficulties, such as outdated or intentionally omitted root certificates making it only possible to use
 plain HTTP, or just other sorts of applications where having to make a web UI just for receiving the authorisation code to complete the token request would be a bother,
 for me such a case would be bots like Satori.
It essentially just replaces three-legged authorisation from OAuth 1.0a but without the needlessly complex annoying aspects of OAuth 1.0a.

Beyond that I'm also just sick of entering my ridiculously long, randomly generated password letter by letter on the inaccurate touch screen of the Nintendo 3DS.
2024-07-30 13:08:22 +00:00

164 lines
5.7 KiB
JavaScript

#include loading.jsx
#include app/info.jsx
#include app/scope.jsx
#include header/header.js
#include header/user.jsx
const HanyuuOAuth2Verify = () => {
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 verifyAuthsRequest = async approve => {
return await $x.post('/oauth2/verify', { type: 'json' }, {
_csrfp: HanyuuCSRFP.getToken(),
code: userCode,
approve: approve === true ? 'yes' : 'no',
});
};
const handleVerifyAuthsResponse = result => {
const response = result.body();
if(!response) {
alert('Request to verify endpoint failed. Please try again.');
loading.visible = false;
fAuths.classList.remove('hidden');
return;
}
if(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 authorisation request.');
else if(response.error === 'approval')
alert('The 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;
verifyAuthsRequest(ev.submitter.value === 'yes')
.then(handleVerifyAuthsResponse);
};
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/resolve-request?csrfp=${encodeURIComponent(HanyuuCSRFP.getToken())}&code=${encodeURIComponent(eUserCode.value)}`, { type: 'json' })
.then(result => {
const response = result.body();
if(!response) {
alert('Request to resolve endpoint failed. Please try again.');
loading.visible = false;
fCode.classList.remove('hidden');
return;
}
if(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 authorisation request.');
else if(response.error === 'approval')
alert('The 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.req.code;
userHeader = new HanyuuOAuth2UserHeader(response.user);
header.setElement(userHeader);
if(response.app.trusted && response.user.guise === undefined) {
if(userHeader)
userHeader.guiseVisible = false;
verifyAuthsRequest(true).then(handleVerifyAuthsResponse);
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');
}
};