diff --git a/app/assets/css/launcher.css b/app/assets/css/launcher.css index 56816997..9fbcf949 100644 --- a/app/assets/css/launcher.css +++ b/app/assets/css/launcher.css @@ -613,8 +613,7 @@ body, button { font-weight: bold; letter-spacing: 2px; border: none; - padding: 15px 5px; - margin: 10px 0px; + margin: 15px 0px; cursor: pointer; position: relative; right: -20px; @@ -689,6 +688,21 @@ body, button { width: 16px; height: 16px; } +.circle-loader-big { + margin:auto; + border: 5px solid rgba(255, 255, 255, 0.5); + border-left-color: #ffffff; + animation-name: loader-spin; + animation-duration: 1s; + animation-iteration-count: infinite; + animation-timing-function: linear; + position: relative; + display: block; + align-self: center; + border-radius: 50%; + width: 60px; + height: 60px; +} .load-complete { animation: none; border-color: #ffffff; @@ -859,6 +873,29 @@ body, button { transform: rotate(45deg); } +#loginMSButton { + background: none; + border: none; + margin-top: 5px; + margin-bottom: 10px; + font-size: 20px; +} +#loginMSButton:disabled { + color: rgba(255, 255, 255, 0.75); + pointer-events: none; +} + +#loginMSButton:hover, +#loginMSButton:focus { + text-shadow: 0px 0px 20px #fff; + outline: none; +} + +#loginMSButton:active { + color: #c7c7c7; + text-shadow: 0px 0px 20px #c7c7c7; +} + /* #login_filter { height: calc(100% - 22px); diff --git a/app/assets/images/microsoft.svg b/app/assets/images/microsoft.svg new file mode 100644 index 00000000..a45f5fc9 --- /dev/null +++ b/app/assets/images/microsoft.svg @@ -0,0 +1 @@ +Microsoft logo diff --git a/app/assets/js/authmanager.js b/app/assets/js/authmanager.js index 22b2fed9..415029f5 100644 --- a/app/assets/js/authmanager.js +++ b/app/assets/js/authmanager.js @@ -12,9 +12,62 @@ const ConfigManager = require('./configmanager') const LoggerUtil = require('./loggerutil') const Mojang = require('./mojang') +const Microsoft = require('./microsoft') const logger = LoggerUtil('%c[AuthManager]', 'color: #a02d2a; font-weight: bold') const loggerSuccess = LoggerUtil('%c[AuthManager]', 'color: #209b07; font-weight: bold') +async function validateSelectedMojang() { + const current = ConfigManager.getSelectedAccount() + const isValid = await Mojang.validate(current.accessToken, ConfigManager.getClientToken()) + if (!isValid) { + try { + const session = await Mojang.refresh(current.accessToken, ConfigManager.getClientToken()) + ConfigManager.updateAuthAccount(current.uuid, session.accessToken) + ConfigManager.save() + } catch (err) { + logger.debug('Error while validating selected profile:', err) + if (err && err.error === 'ForbiddenOperationException') { + // What do we do? + } + logger.log('Account access token is invalid.') + return false + } + loggerSuccess.log('Account access token validated.') + return true + } else { + loggerSuccess.log('Account access token validated.') + return true + } +} + +async function validateSelectedMicrosoft() { + const current = ConfigManager.getSelectedAccount() + const now = new Date().getTime() + const MCExpiresAt = Date.parse(current.expiresAt) + const MCExpired = now > MCExpiresAt + + if (!MCExpired) { + return true + } + + const MSExpiresAt = Date.parse(current.microsoft.expires_at) + const MSExpired = now > MSExpiresAt + + if (MSExpired) { + const newAccessToken = await Microsoft.refreshAccessToken(current.microsoft.refresh_token) + const newMCAccessToken = await Microsoft.authMinecraft(newAccessToken.access_token) + ConfigManager.updateAuthAccount(current.uuid, newMCAccessToken.access_token, newAccessToken.expires_at) + ConfigManager.save() + return true + } + const newMCAccessToken = await Microsoft.authMinecraft(current.microsoft.access_token) + ConfigManager.updateAuthAccount(current.uuid, newMCAccessToken.access_token, current.microsoft.access_token, current.microsoft.expires_at, newMCAccessToken.expires_at) + ConfigManager.save() + + return true +} + +// Exports // Functions /** @@ -39,7 +92,7 @@ exports.addAccount = async function(username, password){ } else { throw new Error('NotPaidAccount') } - + } catch (err){ return Promise.reject(err) } @@ -53,15 +106,16 @@ exports.addAccount = async function(username, password){ * @returns {Promise.} Promise which resolves to void when the action is complete. */ exports.removeAccount = async function(uuid){ - try { - const authAcc = ConfigManager.getAuthAccount(uuid) - await Mojang.invalidate(authAcc.accessToken, ConfigManager.getClientToken()) + const authAcc = ConfigManager.getAuthAccount(uuid) + if (authAcc.type === 'microsoft') { ConfigManager.removeAuthAccount(uuid) ConfigManager.save() - return Promise.resolve() - } catch (err){ - return Promise.reject(err) + return } + await Mojang.invalidate(authAcc.accessToken, ConfigManager.getClientToken()) + ConfigManager.removeAuthAccount(uuid) + ConfigManager.save() + return } /** @@ -77,23 +131,31 @@ exports.removeAccount = async function(uuid){ exports.validateSelected = async function(){ const current = ConfigManager.getSelectedAccount() const isValid = await Mojang.validate(current.accessToken, ConfigManager.getClientToken()) - if(!isValid){ - try { - const session = await Mojang.refresh(current.accessToken, ConfigManager.getClientToken()) - ConfigManager.updateAuthAccount(current.uuid, session.accessToken) - ConfigManager.save() - } catch(err) { - logger.debug('Error while validating selected profile:', err) - if(err && err.error === 'ForbiddenOperationException'){ - // What do we do? - } - logger.log('Account access token is invalid.') - return false - } - loggerSuccess.log('Account access token validated.') - return true - } else { - loggerSuccess.log('Account access token validated.') + + if (isValid) { return true } -} \ No newline at end of file + + if (ConfigManager.getSelectedAccount() === 'microsoft') { + const validate = await validateSelectedMicrosoft() + return validate + } else { + const validate = await validateSelectedMojang() + return validate + } +} + +exports.addMSAccount = async authCode => { + const accessToken = await Microsoft.getAccessToken(authCode) + const MCAccessToken = await Microsoft.authMinecraft(accessToken.access_token) + const minecraftBuyed = await Microsoft.checkMCStore(MCAccessToken.access_token) + if (!minecraftBuyed) + throw { + message: 'You didn\'t buy Minecraft! Please use another Microsoft account or buy Minecraft.' + } + const MCProfile = await Microsoft.getMCProfile(MCAccessToken.access_token) + const result = ConfigManager.addMsAuthAccount(MCProfile.id, MCAccessToken.access_token, MCProfile.name, MCAccessToken.expires_at, accessToken.access_token, accessToken.refresh_token) + ConfigManager.save() + + return result +} diff --git a/app/assets/js/configmanager.js b/app/assets/js/configmanager.js index 2c0bb53c..5bb85bc4 100644 --- a/app/assets/js/configmanager.js +++ b/app/assets/js/configmanager.js @@ -103,7 +103,8 @@ const DEFAULT_CONFIG = { selectedServer: null, // Resolved selectedAccount: null, authenticationDatabase: {}, - modConfigurations: [] + modConfigurations: [], + microsoftAuth: {} } let config = null @@ -330,6 +331,27 @@ exports.updateAuthAccount = function(uuid, accessToken){ return config.authenticationDatabase[uuid] } +/** + * Update the tokens of an authenticated microsoft account. + * + * @param {string} uuid The uuid of the authenticated account. + * @param {string} accessToken The new Access Token. + * @param {string} msAccessToken The new Microsoft Access Token + * @param {string} msRefreshToken The new Microsoft Refresh Token + * @param {date} msExpires The date when the microsoft access token expires + * @param {date} mcExpires The date when the mojang access token expires + * + * @returns {Object} The authenticated account object created by this action. + */ +exports.updateAuthAccount = function (uuid, accessToken, msAccessToken, msRefreshToken, msExpires, mcExpires) { + config.authenticationDatabase[uuid].accessToken = accessToken + config.authenticationDatabase[uuid].expiresAt = mcExpires + config.authenticationDatabase[uuid].microsoft.access_token = msAccessToken + config.authenticationDatabase[uuid].microsoft.refresh_token = msRefreshToken + config.authenticationDatabase[uuid].microsoft.expires_at = msRefreshToken + return config.authenticationDatabase[uuid] +} + /** * Adds an authenticated account to the database to be stored. * @@ -346,7 +368,39 @@ exports.addAuthAccount = function(uuid, accessToken, username, displayName){ accessToken, username: username.trim(), uuid: uuid.trim(), - displayName: displayName.trim() + displayName: displayName.trim(), + type: 'mojang' + } + return config.authenticationDatabase[uuid] +} + +/** + * Adds an authenticated microsoft account to the database to be stored. + * + * @param {string} uuid The uuid of the authenticated account. + * @param {string} accessToken The accessToken of the authenticated account. + * @param {string} name The in game name of the authenticated account. + * @param {date} mcExpires The date when the mojang access token expires + * @param {string} msAccessToken The microsoft access token + * @param {string} msRefreshToken The microsoft refresh token + * @param {date} msExpires The date when the microsoft access token expires + * + * @returns {Object} The authenticated account object created by this action. + */ +exports.addMsAuthAccount = function (uuid, accessToken, name, mcExpires, msAccessToken, msRefreshToken, msExpires) { + config.selectedAccount = uuid + config.authenticationDatabase[uuid] = { + accessToken, + username: name.trim(), + uuid: uuid.trim(), + displayName: name.trim(), + expiresAt: mcExpires, + type: 'microsoft', + microsoft: { + access_token: msAccessToken, + refresh_token: msRefreshToken, + expires_at: msExpires + } } return config.authenticationDatabase[uuid] } diff --git a/app/assets/js/microsoft.js b/app/assets/js/microsoft.js new file mode 100644 index 00000000..e6762914 --- /dev/null +++ b/app/assets/js/microsoft.js @@ -0,0 +1,162 @@ +const got = require('got').extend({ + responseType: 'json', + resolveBodyOnly: true +}) + +// TODO: Add client ID (https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade) +const CLIENT_ID = '' + +const TOKEN_URI = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/token' +const AUTH_XBL_URI = 'https://user.auth.xboxlive.com/user/authenticate' +const AUTH_XSTS_URI = 'https://xsts.auth.xboxlive.com/xsts/authorize' +const AUTH_MC_URI = 'https://api.minecraftservices.com/authentication/login_with_xbox' +const PROFILE_URI = 'https://api.minecraftservices.com/minecraft/profile' + +async function getXBLToken(accessToken) { + const { + Token: token, + DisplayClaims: displayClaims + } = await got.post(AUTH_XBL_URI, { + json: { + Properties: { + AuthMethod: 'RPS', + SiteName: 'user.auth.xboxlive.com', + RpsTicket: `d=${accessToken}` + }, + RelyingParty: 'http://auth.xboxlive.com', + TokenType: 'JWT' + } + }) + + return { + token, + uhs: displayClaims.xui[0].uhs + } +} + +async function getXSTSToken(XBLToken) { + const data = await got.post(AUTH_XSTS_URI, { + json: { + Properties: { + SandboxId: 'RETAIL', + UserTokens: [XBLToken] + }, + RelyingParty: 'rp://api.minecraftservices.com/', + TokenType: 'JWT' + } + }) + + if (data.XErr) { + switch (data.XErr) { + case 2148916233: + throw { + message: 'Your Microsoft account is not connected to an Xbox account. Please create one.
' + } + case 2148916238: + throw { + message: 'Since you are not yet 18 years old, an adult must add you to a family in order for you to use Helios Launcher!' + } + } + throw data + } + + return data.Token +} + +async function getMCAccessToken(UHS, XSTSToken) { + const data = await got.post(AUTH_MC_URI, { + json: { + identityToken: `XBL3.0 x=${UHS};${XSTSToken}` + } + }) + + const expiresAt = new Date() + expiresAt.setSeconds(expiresAt.getSeconds() + data.expires_in) + + return { + expired_at: expiresAt, + access_token: data.access_token + } +} + +exports.getAccessToken = async authCode => { + const { + expires_in, + access_token, + refresh_token + } = await got.post(TOKEN_URI, { + form: { + client_id: CLIENT_ID, + code: authCode, + scope: 'XboxLive.signin', + redirect_uri: 'https://login.microsoftonline.com/common/oauth2/nativeclient', + grant_type: 'authorization_code' + } + }) + + const expiresAt = new Date() + expiresAt.setSeconds(expiresAt.getSeconds() + expires_in) + + return { + expires_at: expiresAt, + access_token, + refresh_token + } +} + +exports.refreshAccessToken = async refreshToken => { + const { + expires_in, + access_token + } = await got.post(TOKEN_URI, { + form: { + client_id: CLIENT_ID, + refresh_token: refreshToken, + scope: 'XboxLive.signin', + redirect_uri: 'https://login.microsoftonline.com/common/oauth2/nativeclient', + grant_type: 'refresh_token' + }, + responseType: 'json' + }) + + const expiresAt = new Date() + expiresAt.setSeconds(expiresAt.getSeconds() + expires_in) + + return { + expires_at: expiresAt, + access_token + } +} + +exports.authMinecraft = async accessToken => { + const XBLToken = await getXBLToken(accessToken) + const XSTSToken = await getXSTSToken(XBLToken.token) + const MCToken = await getMCAccessToken(XBLToken.uhs, XSTSToken) + + return MCToken +} + +exports.checkMCStore = async access_token => { + try { + const {items} = await got('https://api.minecraftservices.com/entitlements/mcstore', { + headers: { + Authorization: 'Bearer ' + access_token + }, + responseType: 'json' + }) + + return items && items.length > 0 + } catch { + return false + } +} + +exports.getMCProfile = async MCAccessToken => { + const data = await got(PROFILE_URI, { + headers: { + Authorization: `Bearer ${MCAccessToken}` + } + }) + + return data +} \ No newline at end of file diff --git a/app/assets/js/scripts/login.js b/app/assets/js/scripts/login.js index 34078bd1..3629c9f0 100644 --- a/app/assets/js/scripts/login.js +++ b/app/assets/js/scripts/login.js @@ -17,6 +17,7 @@ const checkmarkContainer = document.getElementById('checkmarkContainer') const loginRememberOption = document.getElementById('loginRememberOption') const loginButton = document.getElementById('loginButton') const loginForm = document.getElementById('loginForm') +const loginMSButton = document.getElementById('loginMSButton') // Control variables. let lu = false, lp = false @@ -297,4 +298,95 @@ loginButton.addEventListener('click', () => { loggerLogin.log('Error while logging in.', err) }) -}) \ No newline at end of file +}) + +loginMSButton.addEventListener('click', () => { + // Show loading stuff. + toggleOverlay(true, false, 'msOverlay') + loginMSButton.disabled = true + ipcRenderer.send('openMSALoginWindow', 'open') +}) + +ipcRenderer.on('MSALoginWindowReply', (_, ...arguments_) => { + if (arguments_[0] === 'error') { + loginMSButton.disabled = false + loginLoading(false) + switch (arguments_[1]) { + case 'AlreadyOpenException': { + setOverlayContent('ERROR', 'There is already a login window open!', 'OK') + setOverlayHandler(() => { + toggleOverlay(false) + toggleOverlay(false, false, 'msOverlay') + }) + toggleOverlay(true) + return + } + case 'AuthNotFinished': { + setOverlayContent('ERROR', 'You have to finish the login process to use Helios Launcher. The window will close by itself when you have successfully logged in.', 'OK') + setOverlayHandler(() => { + toggleOverlay(false) + toggleOverlay(false, false, 'msOverlay') + }) + toggleOverlay(true) + return + } + } + + } + toggleOverlay(false, false, 'msOverlay') + const queryMap = arguments_[0] + if (queryMap.has('error')) { + let error = queryMap.get('error') + let errorDesc = queryMap.get('error_description') + if (error === 'access_denied') { + error = 'ERRPR' + errorDesc = 'To use the Helios Launcher, you must agree to the required permissions! Otherwise you can\'t use this launcher with Microsoft accounts.

Despite agreeing to the permissions you don\'t give us the possibility to do anything with your account, because all data will always be sent back to you (the launcher) IMMEDIATELY and WITHOUT WAY.' + } + setOverlayContent(error, errorDesc, 'OK') + setOverlayHandler(() => { + loginMSButton.disabled = false + toggleOverlay(false) + }) + toggleOverlay(true) + return + } + + // Disable form. + formDisabled(true) + + const authCode = queryMap.get('code') + AuthManager.addMSAccount(authCode).then(account => { + updateSelectedAccount(account) + loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.loggingIn'), Lang.queryJS('login.success')) + $('.circle-loader').toggleClass('load-complete') + $('.checkmark').toggle() + setTimeout(() => { + switchView(VIEWS.login, loginViewOnSuccess, 500, 500, () => { + // Temporary workaround + if (loginViewOnSuccess === VIEWS.settings) { + prepareSettings() + } + loginViewOnSuccess = VIEWS.landing // Reset this for good measure. + loginCancelEnabled(false) // Reset this for good measure. + loginViewCancelHandler = null // Reset this for good measure. + loginUsername.value = '' + loginPassword.value = '' + $('.circle-loader').toggleClass('load-complete') + $('.checkmark').toggle() + loginLoading(false) + loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.success'), Lang.queryJS('login.login')) + formDisabled(false) + }) + }, 1000) + }).catch(error => { + loginMSButton.disabled = false + loginLoading(false) + setOverlayContent('ERROR', error.message ? error.message : 'An error occurred while logging in with Microsoft! For more detailed information please check the log. You can open it with CTRL + SHIFT + I.', Lang.queryJS('login.tryAgain')) + setOverlayHandler(() => { + formDisabled(false) + toggleOverlay(false) + }) + toggleOverlay(true) + loggerLogin.error(error) + }) +}) diff --git a/app/assets/js/scripts/settings.js b/app/assets/js/scripts/settings.js index 4a1997fe..8fd6f84d 100644 --- a/app/assets/js/scripts/settings.js +++ b/app/assets/js/scripts/settings.js @@ -381,15 +381,28 @@ function bindAuthAccountLogOut(){ }) } +let data = null + /** * Process a log out. * * @param {Element} val The log out button element. * @param {boolean} isLastAccount If this logout is on the last added account. */ -function processLogOut(val, isLastAccount){ - const parent = val.closest('.settingsAuthAccount') - const uuid = parent.getAttribute('uuid') +function processLogOut(val, isLastAccount, skip = false) { + data = { + val, + isLastAccount + } + if (!skip) { + const parent = val.closest('.settingsAuthAccount') + const uuid = parent.getAttribute('uuid') + const account = ConfigManager.getAuthAccount(uuid) + if (account.type === 'microsoft') { + toggleOverlay(true, false, 'msOverlay') + ipcRenderer.send('openMSALogoutWindow', 'open') + } + } const prevSelAcc = ConfigManager.getSelectedAccount() AuthManager.removeAccount(uuid).then(() => { if(!isLastAccount && uuid === prevSelAcc.uuid){ @@ -404,6 +417,11 @@ function processLogOut(val, isLastAccount){ }) } +ipcRenderer.on('MSALogoutWindowReply', (event, ...args) => { + toggleOverlay(false, false, 'msOverlay') + processLogOut(data.val, data.isLastAccount, true) +}) + /** * Refreshes the status of the selected account on the auth account * elements. diff --git a/app/login.ejs b/app/login.ejs index 7ecc4a6c..b622afef 100644 --- a/app/login.ejs +++ b/app/login.ejs @@ -32,7 +32,7 @@ forgot password? @@ -52,6 +52,19 @@ + or
+
Need an Account? diff --git a/app/overlay.ejs b/app/overlay.ejs index 0c18aef4..09ea19b2 100644 --- a/app/overlay.ejs +++ b/app/overlay.ejs @@ -28,6 +28,7 @@
+ Lorem Ipsum:
Finis Illud
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud..
@@ -37,5 +38,11 @@
+ \ No newline at end of file diff --git a/index.js b/index.js index 70cfc81b..e496964e 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,9 @@ const path = require('path') const semver = require('semver') const { pathToFileURL } = require('url') +const redirectUriPrefix = 'https://login.microsoftonline.com/common/oauth2/nativeclient?' +const CLIENT_ID = '' // TODO: Add client ID (https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade) + // Setup auto updater. function initAutoUpdater(event, data) { @@ -87,6 +90,73 @@ ipcMain.on('distributionIndexDone', (event, res) => { // https://electronjs.org/docs/tutorial/offscreen-rendering app.disableHardwareAcceleration() +let MSALoginWindow + +// Open the Microsoft Account Login window +ipcMain.on('openMSALoginWindow', (ipcEvent) => { + if (MSALoginWindow) { + ipcEvent.reply('MSALoginWindowReply', 'error', 'AlreadyOpenException') + return + } + MSALoginWindow = new BrowserWindow({ + title: 'Microsoft Login', + backgroundColor: '#222222', + width: 520, + height: 600, + frame: true, + icon: getPlatformIcon('SealCircle') + }) + + MSALoginWindow.on('closed', () => { + MSALoginWindow = undefined + }) + + MSALoginWindow.on('close', () => { + ipcEvent.reply('MSALoginWindowReply', 'error', 'AuthNotFinished') + }) + + MSALoginWindow.webContents.on('did-navigate', (_, uri) => { + if (uri.startsWith(redirectUriPrefix)) { + let queries = uri.substring(redirectUriPrefix.length).split('#', 1).toString().split('&') + let queryMap = new Map() + + queries.forEach(query => { + const [name, value] = query.split('=') + queryMap.set(name, decodeURI(value)) + }) + + ipcEvent.reply('MSALoginWindowReply', queryMap) + + MSALoginWindow.close() + MSALoginWindow = null + } + }) + + MSALoginWindow.removeMenu() + MSALoginWindow.loadURL('https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?prompt=select_account&client_id=' + CLIENT_ID + '&response_type=code&scope=XboxLive.signin%20offline_access&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient') +}) + +let MSALogoutWindow + +ipcMain.on('openMSALogoutWindow', (ipcEvent) => { + if (!MSALogoutWindow) { + MSALogoutWindow = new BrowserWindow({ + title: 'Microsoft Logout', + backgroundColor: '#222222', + width: 520, + height: 600, + frame: true, + icon: getPlatformIcon('SealCircle') + }) + MSALogoutWindow.loadURL('https://login.microsoftonline.com/common/oauth2/v2.0/logout') + MSALogoutWindow.webContents.on('did-navigate', () => { + setTimeout(() => { + ipcEvent.reply('MSALogoutWindowReply') + }, 5000) + }) + } +}) + // https://github.com/electron/electron/issues/18397 app.allowRendererProcessReuse = true diff --git a/package-lock.json b/package-lock.json index 1005ec70..04447165 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,6 +63,68 @@ "sumchecker": "^3.0.1" }, "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -74,6 +136,40 @@ "universalify": "^0.1.0" } }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -83,6 +179,42 @@ "graceful-fs": "^4.1.6" } }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -215,18 +347,27 @@ } }, "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" }, "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "requires": { - "defer-to-connect": "^1.0.1" + "defer-to-connect": "^2.0.0" + } + }, + "@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" } }, "@types/debug": { @@ -255,6 +396,19 @@ "@types/node": "*" } }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + }, + "@types/keyv": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", + "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "requires": { + "@types/node": "*" + } + }, "@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -265,8 +419,7 @@ "@types/node": { "version": "14.17.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", - "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==", - "dev": true + "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==" }, "@types/plist": { "version": "3.0.2", @@ -279,6 +432,14 @@ "xmlbuilder": ">=11.0.1" } }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "requires": { + "@types/node": "*" + } + }, "@types/semver": { "version": "7.3.6", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.6.tgz", @@ -524,15 +685,6 @@ "tweetnacl": "^0.14.3" } }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -766,36 +918,23 @@ "sax": "^1.2.4" } }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" + }, "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", + "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - } + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" } }, "callsites": { @@ -931,7 +1070,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -1099,12 +1237,18 @@ } }, "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "requires": { - "mimic-response": "^1.0.0" + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + } } }, "deep-extend": { @@ -1120,10 +1264,9 @@ "dev": true }, "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" }, "define-properties": { "version": "1.1.3", @@ -1171,12 +1314,11 @@ } }, "discord-rpc": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-4.0.1.tgz", - "integrity": "sha512-HOvHpbq5STRZJjQIBzwoKnQ0jHplbEWFWlPDwXXKm/bILh4nzjcg7mNqll0UY7RsjFoaXA7e/oYb/4lvpda2zA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/discord-rpc/-/discord-rpc-3.2.0.tgz", + "integrity": "sha512-KJv0EVbGMlr04HoG6f5b3wD7X9kSHzQ2Ed2qfHSDvYJ1MkE8RbCQmMcQQrSvAxpfsqZgUjB/bsfi/mjyicCH+A==", "requires": { "node-fetch": "^2.6.1", - "register-scheme": "github:devsnek/node-register-scheme", "ws": "^7.3.1" } }, @@ -1869,12 +2011,6 @@ "flat-cache": "^3.0.4" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, "filelist": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", @@ -1948,10 +2084,9 @@ "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "requires": { "pump": "^3.0.0" } @@ -2066,22 +2201,21 @@ } }, "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", + "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" } }, "graceful-fs": { @@ -2132,8 +2266,7 @@ "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-signature": { "version": "1.2.0", @@ -2145,6 +2278,15 @@ "sshpk": "^1.7.0" } }, + "http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, "iconv-corefoundation": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.6.tgz", @@ -2354,10 +2496,9 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "json-schema": { "version": "0.2.3", @@ -2410,12 +2551,11 @@ } }, "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", "requires": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "latest-version": { @@ -2477,10 +2617,9 @@ "dev": true }, "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" }, "lru-cache": { "version": "6.0.0", @@ -2547,8 +2686,7 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, "minimatch": { "version": "3.0.4", @@ -2593,6 +2731,7 @@ "version": "1.7.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, "optional": true }, "node-fetch": { @@ -2601,10 +2740,9 @@ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, "npm-conf": { "version": "1.1.3", @@ -2652,10 +2790,9 @@ } }, "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" }, "package-json": { "version": "6.5.0", @@ -2669,6 +2806,138 @@ "semver": "^6.2.0" }, "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2801,6 +3070,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -2842,15 +3116,6 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, - "register-scheme": { - "version": "github:devsnek/node-register-scheme#e7cc9a63a1f512565da44cb57316d9fb10750e17", - "from": "github:devsnek/node-register-scheme", - "optional": true, - "requires": { - "bindings": "^1.3.0", - "node-addon-api": "^1.3.0" - } - }, "registry-auth-token": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", @@ -2908,6 +3173,11 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, + "resolve-alpn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.0.tgz", + "integrity": "sha512-e4FNQs+9cINYMO5NMFc6kOUCdohjqFPSgMuwuZAOUWqrfWsen+Yjy5qZFkV5K7VO7tFSLKcUL97olkED7sCBHA==" + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2915,12 +3185,11 @@ "dev": true }, "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", "requires": { - "lowercase-keys": "^1.0.0" + "lowercase-keys": "^2.0.0" } }, "rimraf": { @@ -3640,9 +3909,9 @@ } }, "ws": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", - "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==" + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==" }, "xdg-basedir": { "version": "4.0.0", diff --git a/package.json b/package.json index 7adee673..aacc66da 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "electron-updater": "^4.3.9", "fs-extra": "^10.0.0", "github-syntax-dark": "^0.5.0", + "got": "^11.8.2", "jquery": "^3.6.0", "request": "^2.88.2", "semver": "^7.3.5",