sdp-request-watcher/src/auth.js

80 lines
2.3 KiB
JavaScript

const axios = require('axios');
async function getDeviceCode(clientId) {
const params = new URLSearchParams({
client_id: clientId,
scope: 'SDPOnDemand.requests.READ',
grant_type: 'device_request',
access_type: 'offline'
});
const res = await axios.post('https://accounts.zoho.com/oauth/v3/device/code', params);
return res.data;
}
function pollForToken(clientId, clientSecret, deviceCode, interval, expiresIn) {
const pollParams = new URLSearchParams({
client_id: clientId,
client_secret: clientSecret,
code: deviceCode,
grant_type: 'device_token'
});
return new Promise((resolve, reject) => {
const deadline = Date.now() + (expiresIn || 300) * 1000;
const timer = setInterval(async () => {
if (Date.now() > deadline) {
clearInterval(timer);
reject(new Error('Expired try again.'));
return;
}
try {
const res = await axios.post('https://accounts.zoho.com/oauth/v3/device/token', pollParams);
if (res.data.access_token) {
clearInterval(timer);
resolve(res.data.access_token);
}
} catch (err) {
}
}, interval + 500);
});
}
async function startAuthentication({ clientId, clientSecret, state }) {
state.auth = 'pending';
state.lastError = null;
const deviceData = await getDeviceCode(clientId);
state.verificationUrl = deviceData.verification_uri_complete;
state.userCode = deviceData.user_code;
console.log('Open this URL and authorize:', deviceData.verification_uri_complete);
console.log('Code: ', deviceData.user_code);
try {
const accessToken = await pollForToken(
clientId,
clientSecret,
deviceData.device_code,
deviceData.interval,
deviceData.expires_in
);
state.auth = 'connected';
state.verificationUrl = null;
state.userCode = null;
return { accessToken };
} catch (err) {
state.auth = 'error';
state.lastError = err.message;
state.verificationUrl = null;
state.userCode = null;
return null;
}
}
module.exports = {
startAuthentication
};