import { Validator, Schema } from 'jsonschema'; import { GitHubCodespacesPlatformInfo, GitHubCodespacesPlatformInfoInternal, WebEditorPlatformInfo } from './types'; import { TAuthorizePlatformInternal, TAuthorizePlatform, TAuthorizeWebEditorPlatform } from './types'; const validator = new Validator(); const baseSchema = require('./schemas/schema-base.json'); const extendedSchema = require('./schemas/schema-extended.json'); const authorizePlatformUtility = async ( endpoint: string, data: GitHubCodespacesPlatformInfo | GitHubCodespacesPlatformInfoInternal ) => { const { codespaceToken } = data; if (!codespaceToken) { throw new Error('No `Codespace` token set.'); } // Create
element to initiate the top-level HTTP POST request. const formEl = document.createElement('form'); const originUrl = new URL(endpoint); formEl.setAttribute('action', originUrl.toString()); formEl.setAttribute('method', 'POST'); // create the hidden input elements const codespaceTokenInput = document.createElement('input'); const partnerInfoInput = document.createElement('input'); // set the Codespace token codespaceTokenInput.name = 'codespaceToken'; codespaceTokenInput.value = codespaceToken; // set the partner info partnerInfoInput.name = 'partnerInfo'; partnerInfoInput.value = JSON.stringify(data); // append the form to the DOM formEl.appendChild(codespaceTokenInput); formEl.appendChild(partnerInfoInput); document.body.append(formEl); // submit the form to initiate the top-level HTTP POST formEl.submit(); }; const authorizeWebEditorUtility = async ( endpoint: string, data: WebEditorPlatformInfo ) => { // Create element to initiate the top-level HTTP POST request. const formEl = document.createElement('form'); const originUrl = new URL(endpoint); formEl.setAttribute('action', originUrl.toString()); formEl.setAttribute('method', 'POST'); // create the hidden input elements and set partner info const partnerInfoInput = document.createElement('input'); partnerInfoInput.name = 'partnerInfo'; partnerInfoInput.value = JSON.stringify(data); // append the form to the DOM formEl.appendChild(partnerInfoInput); document.body.append(formEl); // submit the form to initiate the top-level HTTP POST formEl.submit(); }; /** * Utility to validate a payload with a JSON schema. * @param instance Payload. * @param schema JSON schema. */ const validateBySchemaUtility = ( instance: GitHubCodespacesPlatformInfo | GitHubCodespacesPlatformInfoInternal | WebEditorPlatformInfo, schema: Schema ) => { const validationResult = validator.validate(instance, schema); if (validationResult.errors.length) { throw new Error(validationResult.errors[0].message); } }; /** * Function to authorize GitHub Codespaces platform workbench with a top-level HTTP POST. * * @param endpoint GitHub Codespaces authentication endpoint. * @param data GitHub Codespaces partner info (VSCodespacesPlatformInfo). */ export const authorizePlatform: TAuthorizePlatform = async (endpoint: string, data: GitHubCodespacesPlatformInfo) => { validateBySchemaUtility(data, baseSchema); return await authorizePlatformUtility(endpoint, data); }; /** * Function to authorize GitHub Codespaces platform workbench with a top-level HTTP POST with internal API surface. * * @param endpoint GitHub Codespaces authentication endpoint. * @param data GitHub Codespaces partner info (VSCodespacesPlatformInfoInternal). */ export const authorizePlatformInternal: TAuthorizePlatformInternal = async ( endpoint: string, data: GitHubCodespacesPlatformInfoInternal ) => { validateBySchemaUtility(data, extendedSchema); return await authorizePlatformUtility(endpoint, data); }; /** * Function to authorize Web Editor workbench with a top-level HTTP POST with internal API surface. * * @param endpoint GitHub Codespaces Web Editor authentication endpoint. * @param data GitHub Codespaces Web Editor partner info (WebEditorPlatformInfo). */ export const authorizeWebEditorPlatform: TAuthorizeWebEditorPlatform = async ( endpoint: string, data: WebEditorPlatformInfo ) => { validateBySchemaUtility(data, extendedSchema); return await authorizeWebEditorUtility(endpoint, data); };