mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-11-14 12:49:28 +00:00
- Updated `@theia/*` to `1.37.0`. - Fixed all `yarn audit` security vulnerabilities. - Updated to `electron@23.2.4`: - `contextIsolation` is `true`, - `nodeIntegration` is `false`, and the - `webpack` target is moved from `electron-renderer` to `web`. - Updated to `typescript@4.9.3`. - Updated the `eslint` plugins. - Added the new `Light High Contrast` theme to the IDE2. - High contrast themes use Theia APIs for style adjustments. - Support for ESM modules: `"moduleResolution": "node16"`. - Node.js >= 16.14 is required. - VISX langage packs were bumped to `1.70.0`. - Removed undesired editor context menu items. (Closes #1394) Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
113 lines
3.4 KiB
TypeScript
113 lines
3.4 KiB
TypeScript
import jwt_decode from 'jwt-decode';
|
|
import { sha256 } from 'hash.js';
|
|
import { randomBytes } from 'node:crypto';
|
|
import btoa from 'btoa';
|
|
import { AuthenticationSession } from './types';
|
|
import { Unknown } from '../../common/nls';
|
|
|
|
export interface IToken {
|
|
accessToken: string; // When unable to refresh due to network problems, the access token becomes undefined
|
|
idToken?: string; // depending on the scopes can be either supplied or empty
|
|
|
|
expiresIn?: number; // How long access token is valid, in seconds
|
|
expiresAt?: number; // UNIX epoch time at which token will expire
|
|
refreshToken: string;
|
|
|
|
account: {
|
|
id: string;
|
|
email: string;
|
|
nickname: string;
|
|
picture: string;
|
|
};
|
|
scope: string;
|
|
sessionId: string;
|
|
}
|
|
export namespace IToken {
|
|
// check if the token is expired or will expired before the buffer
|
|
export function requiresRefresh(token: IToken, buffer: number): boolean {
|
|
return token.expiresAt ? token.expiresAt < Date.now() + buffer : false;
|
|
}
|
|
}
|
|
|
|
export interface Token {
|
|
access_token: string;
|
|
id_token?: string;
|
|
refresh_token: string;
|
|
scope: 'offline_access' | string; // `offline_access`
|
|
expires_in: number; // expires in seconds
|
|
token_type: string; // `Bearer`
|
|
}
|
|
|
|
export type RefreshToken = Omit<Token, 'refresh_token'>;
|
|
|
|
export function token2IToken(token: Token): IToken {
|
|
const parsedIdToken: any =
|
|
(token.id_token && jwt_decode(token.id_token)) || {};
|
|
|
|
return {
|
|
/*
|
|
* ".id_token" is already decoded for account details above
|
|
* so we probably don't need to keep it around as "idToken".
|
|
* If we do, and subsequently try to store it with
|
|
* Windows Credential Manager (WCM) it's probable we'll
|
|
* exceed WCMs' 2500 password character limit breaking
|
|
* our auth functionality
|
|
*/
|
|
// ! idToken: token.id_token,
|
|
expiresIn: token.expires_in,
|
|
expiresAt: token.expires_in
|
|
? Date.now() + token.expires_in * 1000
|
|
: undefined,
|
|
accessToken: token.access_token,
|
|
refreshToken: token.refresh_token,
|
|
sessionId: parsedIdToken.sub,
|
|
scope: token.scope,
|
|
account: {
|
|
id: parsedIdToken.sub || Unknown,
|
|
email: parsedIdToken.email || Unknown,
|
|
nickname: parsedIdToken.nickname || Unknown,
|
|
picture: parsedIdToken.picture || Unknown,
|
|
},
|
|
};
|
|
}
|
|
|
|
export function IToken2Session(token: IToken): AuthenticationSession {
|
|
return {
|
|
accessToken: token.accessToken,
|
|
account: {
|
|
id: token.account.id,
|
|
label: token.account.nickname,
|
|
picture: token.account.picture,
|
|
email: token.account.email,
|
|
},
|
|
id: token.account.id,
|
|
scopes: token.scope.split(' '),
|
|
};
|
|
}
|
|
|
|
export function getRandomValues(input: Uint8Array): Uint8Array {
|
|
const bytes = randomBytes(input.length);
|
|
for (let i = 0, n = bytes.length; i < n; ++i) {
|
|
input[i] = bytes[i];
|
|
}
|
|
return input;
|
|
}
|
|
|
|
export function generateProofKeyPair() {
|
|
const urlEncode = (str: string) =>
|
|
str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
const decode = (buffer: Uint8Array | number[]) => {
|
|
let decodedString = '';
|
|
for (let i = 0; i < buffer.length; i++) {
|
|
decodedString += String.fromCharCode(buffer[i]);
|
|
}
|
|
return decodedString;
|
|
};
|
|
const buffer = getRandomValues(new Uint8Array(32));
|
|
const seed = btoa(decode(buffer));
|
|
|
|
const verifier = urlEncode(seed);
|
|
const challenge = urlEncode(btoa(decode(sha256().update(verifier).digest())));
|
|
return { verifier, challenge };
|
|
}
|