From 70b9068dc0eacc1d9adceb1f2f373f7ad0f7c26c Mon Sep 17 00:00:00 2001 From: Robert Gruen Date: Thu, 31 Oct 2024 16:48:37 -0700 Subject: [PATCH] ran prettier --- ts/jest.config.js | 2 +- ts/packages/agentSdk/src/display.ts | 7 +- .../androidMobile/src/androidMobileSchema.ts | 2 +- ts/packages/api/src/index.ts | 1 - ts/packages/api/src/typeAgentServer.ts | 17 ++- ts/packages/api/test/api.spec.ts | 13 +- .../dispatcher/src/agent/agentProcess.ts | 2 +- .../dispatcher/src/agent/agentProcessShim.ts | 8 +- .../dispatcher/src/agent/agentProcessTypes.ts | 6 +- ts/packages/shell/package.json | 2 +- ts/packages/shell/src/main/index.ts | 2 +- .../shell/src/preload/electronTypes.ts | 12 +- ts/packages/shell/src/renderer/index.html | 71 +++++++---- .../shell/src/renderer/src/auth/authConfig.ts | 59 ++++----- .../shell/src/renderer/src/auth/authPopup.ts | 72 +++++------ .../src/renderer/src/auth/authRedirect.ts | 113 ++++++++++-------- .../shell/src/renderer/src/auth/graph.ts | 14 +-- .../src/renderer/src/auth/graphConfig.ts | 2 +- ts/packages/shell/src/renderer/src/auth/ui.ts | 60 ++++++---- .../shell/src/renderer/src/azureSpeech.ts | 12 +- ts/packages/shell/src/renderer/src/main.ts | 9 +- .../shell/src/renderer/src/webSocketAPI.ts | 14 ++- ts/packages/shell/tsconfig.node.json | 7 +- 23 files changed, 294 insertions(+), 213 deletions(-) diff --git a/ts/jest.config.js b/ts/jest.config.js index 3e69d3412..1cd2572af 100644 --- a/ts/jest.config.js +++ b/ts/jest.config.js @@ -8,5 +8,5 @@ module.exports = { moduleNameMapper: { "^../src/(.*)$": "/dist/$1", }, - testTimeout: 30000 + testTimeout: 30000, }; diff --git a/ts/packages/agentSdk/src/display.ts b/ts/packages/agentSdk/src/display.ts index d65c071d3..1b53c22a4 100644 --- a/ts/packages/agentSdk/src/display.ts +++ b/ts/packages/agentSdk/src/display.ts @@ -26,7 +26,12 @@ export type DisplayMessageKind = export type DisplayAppendMode = "inline" | "block" | "temporary"; -export type ClientAction = "show-camera" | "open-app" | "show-notification" | "start-intent" | "set-alarm"; +export type ClientAction = + | "show-camera" + | "open-app" + | "show-notification" + | "start-intent" + | "set-alarm"; export interface ActionIO { readonly type: DisplayType; diff --git a/ts/packages/agents/androidMobile/src/androidMobileSchema.ts b/ts/packages/agents/androidMobile/src/androidMobileSchema.ts index 0dd4c1ad5..e44581750 100644 --- a/ts/packages/agents/androidMobile/src/androidMobileSchema.ts +++ b/ts/packages/agents/androidMobile/src/androidMobileSchema.ts @@ -10,7 +10,7 @@ export type SetAlarmAction = { // the original request of the user originalRequest: string; // the time for the alarm in the format YYYY-mm-ddThh:mm:ss (i.e. 2024-02-15T08:30:15 ) - time: string + time: string; }; }; diff --git a/ts/packages/api/src/index.ts b/ts/packages/api/src/index.ts index b377241ea..d4b09dae7 100644 --- a/ts/packages/api/src/index.ts +++ b/ts/packages/api/src/index.ts @@ -10,4 +10,3 @@ assert(envPath, ".env file not found!"); const typeAgentServer: TypeAgentServer = new TypeAgentServer(envPath); typeAgentServer.start(); - diff --git a/ts/packages/api/src/typeAgentServer.ts b/ts/packages/api/src/typeAgentServer.ts index ba9323c3a..353e0ffe8 100644 --- a/ts/packages/api/src/typeAgentServer.ts +++ b/ts/packages/api/src/typeAgentServer.ts @@ -11,14 +11,16 @@ import { import { WebAPIClientIO } from "./webClientIO.js"; import { TypeAgentAPIWebSocketServer } from "./webSocketServer.js"; - export class TypeAgentServer { private dispatcher: Dispatcher | undefined; private webClientIO: WebAPIClientIO | undefined; private webSocketServer: TypeAgentAPIWebSocketServer | undefined; private webServer: TypeAgentAPIWebServer | undefined; - constructor(private envPath: string, private wsPort: number = 3030) { + constructor( + private envPath: string, + private wsPort: number = 3030, + ) { // typeAgent config dotenv.config({ path: this.envPath }); } @@ -36,9 +38,14 @@ export class TypeAgentServer { }); // websocket server - const hostEndpoint = process.env["WEBSOCKET_HOST"] ?? `ws://localhost:${this.wsPort}`; + const hostEndpoint = + process.env["WEBSOCKET_HOST"] ?? `ws://localhost:${this.wsPort}`; const url = new URL(hostEndpoint); - this.webSocketServer = new TypeAgentAPIWebSocketServer(url, this.dispatcher, this.webClientIO!); + this.webSocketServer = new TypeAgentAPIWebSocketServer( + url, + this.dispatcher, + this.webClientIO!, + ); // web server config const config: TypeAgentAPIServerConfig = JSON.parse( @@ -54,4 +61,4 @@ export class TypeAgentServer { this.webServer?.stop(); this.webSocketServer?.stop(); } -} \ No newline at end of file +} diff --git a/ts/packages/api/test/api.spec.ts b/ts/packages/api/test/api.spec.ts index 6f71edbae..ca3165d79 100644 --- a/ts/packages/api/test/api.spec.ts +++ b/ts/packages/api/test/api.spec.ts @@ -6,13 +6,13 @@ import { TypeAgentServer } from "../src/typeAgentServer.js"; import findConfig from "find-config"; describe("api web/ws server", () => { - it("verify web server respnses", async () => { - const envPath = findConfig(".env"); if (envPath !== null) { assert(envPath, ".env file not found!"); - const typeAgentServer: TypeAgentServer = new TypeAgentServer(envPath!); + const typeAgentServer: TypeAgentServer = new TypeAgentServer( + envPath!, + ); await typeAgentServer.start(); let response = await fetch("http://localhost:3000/"); @@ -26,8 +26,9 @@ describe("api web/ws server", () => { typeAgentServer.stop(); } else { - console.warn("Skipping test 'verify web server respnses', no .env file!"); + console.warn( + "Skipping test 'verify web server respnses', no .env file!", + ); } - }) + }); }); - diff --git a/ts/packages/dispatcher/src/agent/agentProcess.ts b/ts/packages/dispatcher/src/agent/agentProcess.ts index a2e39507f..1b4b8156d 100644 --- a/ts/packages/dispatcher/src/agent/agentProcess.ts +++ b/ts/packages/dispatcher/src/agent/agentProcess.ts @@ -371,7 +371,7 @@ function getActionContextShim( rpc.send("takeAction", { actionContextId, action, - data + data, }); }, }; diff --git a/ts/packages/dispatcher/src/agent/agentProcessShim.ts b/ts/packages/dispatcher/src/agent/agentProcessShim.ts index 962119571..69dcddbd1 100644 --- a/ts/packages/dispatcher/src/agent/agentProcessShim.ts +++ b/ts/packages/dispatcher/src/agent/agentProcessShim.ts @@ -13,7 +13,7 @@ import { CommandDescriptors, ParsedCommandParams, ParameterDefinitions, - ClientAction + ClientAction, } from "@typeagent/agent-sdk"; import { AgentCallFunctions, @@ -244,7 +244,11 @@ export async function createAgentProcessShim( .get(param.actionContextId) .actionIO.appendDisplay(param.content, param.mode); }, - takeAction: (param: { actionContextId: number; action: ClientAction, data?: unknown }) => { + takeAction: (param: { + actionContextId: number; + action: ClientAction; + data?: unknown; + }) => { actionContextMap .get(param.actionContextId) .actionIO.takeAction(param.action, param.data); diff --git a/ts/packages/dispatcher/src/agent/agentProcessTypes.ts b/ts/packages/dispatcher/src/agent/agentProcessTypes.ts index ec9cc0f7f..b8f146c18 100644 --- a/ts/packages/dispatcher/src/agent/agentProcessTypes.ts +++ b/ts/packages/dispatcher/src/agent/agentProcessTypes.ts @@ -33,7 +33,11 @@ export type AgentContextCallFunctions = { content: DisplayContent; mode: DisplayAppendMode; }) => void; - takeAction: (param: { actionContextId: number; action: ClientAction, data?: unknown }) => void; + takeAction: (param: { + actionContextId: number; + action: ClientAction; + data?: unknown; + }) => void; }; export type AgentContextInvokeFunctions = { diff --git a/ts/packages/shell/package.json b/ts/packages/shell/package.json index dfe21d887..c87bbd76e 100644 --- a/ts/packages/shell/package.json +++ b/ts/packages/shell/package.json @@ -45,7 +45,7 @@ "typechat": "^0.1.1", "ws": "^8.17.1" }, - "devDependencies": { + "devDependencies": { "@electron-toolkit/tsconfig": "^1.0.1", "@types/debug": "^4.1.10", "@types/dompurify": "^3.0.5", diff --git a/ts/packages/shell/src/main/index.ts b/ts/packages/shell/src/main/index.ts index 39517d27d..aa489ac95 100644 --- a/ts/packages/shell/src/main/index.ts +++ b/ts/packages/shell/src/main/index.ts @@ -33,7 +33,7 @@ import { AppAgentEvent, DisplayAppendMode } from "@typeagent/agent-sdk"; import { shellAgentProvider } from "./agent.js"; import { BrowserAgentIpc } from "./browserIpc.js"; import { WebSocketMessage } from "common-utils"; -import { AzureSpeech } from "./azureSpeech.js" +import { AzureSpeech } from "./azureSpeech.js"; import { auth } from "aiclient"; console.log(auth.AzureTokenScopes.CogServices); diff --git a/ts/packages/shell/src/preload/electronTypes.ts b/ts/packages/shell/src/preload/electronTypes.ts index d5e25f6d0..b9c5a2138 100644 --- a/ts/packages/shell/src/preload/electronTypes.ts +++ b/ts/packages/shell/src/preload/electronTypes.ts @@ -39,7 +39,11 @@ export interface ClientSettingsProvider { export type DisplayType = "html" | "iframe" | "text"; -export type ClientActions = "show-camera" | "open-app" | "show-notification" | "start-intent"; +export type ClientActions = + | "show-camera" + | "open-app" + | "show-notification" + | "start-intent"; // end duplicate type section @@ -187,7 +191,11 @@ export interface ClientAPI { ) => void, ): void; onTakeAction( - callback: (e: Electron.IpcRendererEvent, action: string, data: unknown) => void, + callback: ( + e: Electron.IpcRendererEvent, + action: string, + data: unknown, + ) => void, ); } diff --git a/ts/packages/shell/src/renderer/index.html b/ts/packages/shell/src/renderer/index.html index 7d76124a8..710a583f5 100644 --- a/ts/packages/shell/src/renderer/index.html +++ b/ts/packages/shell/src/renderer/index.html @@ -15,9 +15,12 @@ - - + @@ -26,43 +29,61 @@ -
-
Vanilla JavaScript SPA calling MS Graph API with MSAL.js
-
-
- diff --git a/ts/packages/shell/src/renderer/src/auth/authConfig.ts b/ts/packages/shell/src/renderer/src/auth/authConfig.ts index fbc9c26d8..55f726b20 100644 --- a/ts/packages/shell/src/renderer/src/auth/authConfig.ts +++ b/ts/packages/shell/src/renderer/src/auth/authConfig.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import * as msal from "@azure/msal-browser" +import * as msal from "@azure/msal-browser"; /** - * Configuration object to be passed to MSAL instance on creation. + * Configuration object to be passed to MSAL instance on creation. * For a full list of MSAL.js configuration parameters, visit: - * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md + * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md */ export const msalConfig = { auth: { @@ -14,7 +14,8 @@ export const msalConfig = { clientId: "de5757b7-986f-4f02-aea1-395670da6da0", //clientId: "04b07795-8ddb-461a-bbee-02f9e1bf7b46", // Full directory URL, in the form of https://login.microsoftonline.com/ - authority: "https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47", + authority: + "https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47", // Full redirect URL, in form of http://localhost:3000 redirectUri: "http://localhost:3000/", }, @@ -22,35 +23,35 @@ export const msalConfig = { cacheLocation: "sessionStorage", // This configures where your cache will be stored storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge }, - system: { - loggerOptions: { - loggerCallback: (level, message, containsPii) => { - if (containsPii) { - return; - } - switch (level) { - case msal.LogLevel.Error: - console.error(message); - return; - case msal.LogLevel.Info: - console.info(message); - return; - case msal.LogLevel.Verbose: - console.debug(message); - return; - case msal.LogLevel.Warning: - console.warn(message); - return; - } - } - } - } + system: { + loggerOptions: { + loggerCallback: (level, message, containsPii) => { + if (containsPii) { + return; + } + switch (level) { + case msal.LogLevel.Error: + console.error(message); + return; + case msal.LogLevel.Info: + console.info(message); + return; + case msal.LogLevel.Verbose: + console.debug(message); + return; + case msal.LogLevel.Warning: + console.warn(message); + return; + } + }, + }, + }, }; /** * Scopes you add here will be prompted for user consent during sign-in. * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request. - * For more information about OIDC scopes, visit: + * For more information about OIDC scopes, visit: * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes */ export const loginRequest = { @@ -63,5 +64,5 @@ export const loginRequest = { */ export const tokenRequest = { scopes: ["https://cognitiveservices.azure.com/.default"], - forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token + forceRefresh: false, // Set this to "true" to skip a cached token and go to the server to get a new token }; diff --git a/ts/packages/shell/src/renderer/src/auth/authPopup.ts b/ts/packages/shell/src/renderer/src/auth/authPopup.ts index 89410b0bc..c13e74bff 100644 --- a/ts/packages/shell/src/renderer/src/auth/authPopup.ts +++ b/ts/packages/shell/src/renderer/src/auth/authPopup.ts @@ -6,10 +6,10 @@ import { AuthResponseCallback } from "./authRedirect.js"; import { loginRequest, msalConfig, tokenRequest } from "./authConfig.js"; export class SPAAuthPopup { - private static instance: SPAAuthPopup; private static initialized: boolean = false; - private static initializedCallbacks: Array = new Array(); + private static initializedCallbacks: Array = + new Array(); public static getInstance = (): SPAAuthPopup => { if (!SPAAuthPopup.instance) { @@ -17,14 +17,15 @@ export class SPAAuthPopup { } return SPAAuthPopup.instance; - } + }; public static IsInitialized(): boolean { return SPAAuthPopup.initialized; } - public static registerInitializationCallback(callback: AuthResponseCallback) { - + public static registerInitializationCallback( + callback: AuthResponseCallback, + ) { if (SPAAuthPopup.initialized) { throw new Error("Authentication already initialized"); } @@ -50,11 +51,11 @@ export class SPAAuthPopup { } else { this.signOut(); } - } + }; await this.myMSALObj.initialize(); - this.myMSALObj.handleRedirectPromise().then((response) => { + this.myMSALObj.handleRedirectPromise().then((response) => { if (response !== null) { this.username = response.account.username; this.token = response.accessToken; @@ -63,13 +64,13 @@ export class SPAAuthPopup { // updateTable(response.account); } else { this.selectAccount(); - + /** * If you already have a session that exists with the authentication server, you can use the ssoSilent() API - * to make request for tokens without interaction, by providing a "login_hint" property. To try this, comment the + * to make request for tokens without interaction, by providing a "login_hint" property. To try this, comment the * line above and uncomment the section below. */ - + // myMSALObj.ssoSilent(silentRequest). // then((response) => { // welcomeUser(response.account.username); @@ -80,21 +81,21 @@ export class SPAAuthPopup { // signIn(); // } // }); - } - + } + SPAAuthPopup.initialized = true; - }) + }); } - selectAccount () { + selectAccount() { /** - * See here for more info on account retrieval: + * See here for more info on account retrieval: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md */ const currentAccounts = this.myMSALObj.getAllAccounts(); - if (!currentAccounts || currentAccounts.length < 1) { + if (!currentAccounts || currentAccounts.length < 1) { return; } else if (currentAccounts.length > 1) { // Add your account choosing logic here @@ -103,7 +104,7 @@ export class SPAAuthPopup { this.token = this.token; this.expires = this.expires; } else if (currentAccounts.length === 1) { - this.username = currentAccounts[0].username + this.username = currentAccounts[0].username; // welcomeUser(currentAccounts[0].username); // updateTable(currentAccounts[0]); this.token = this.token; @@ -112,13 +113,13 @@ export class SPAAuthPopup { } signIn() { - /** * You can pass a custom request object below. This will override the initial configuration. For more information, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request */ - this.myMSALObj.loginPopup(loginRequest) + this.myMSALObj + .loginPopup(loginRequest) .then(async (response) => { if (response !== null) { this.username = response.account.username; @@ -128,10 +129,10 @@ export class SPAAuthPopup { // updateTable(response.account); } else { this.selectAccount(); - + // /** // * If you already have a session that exists with the authentication server, you can use the ssoSilent() API - // * to make request for tokens without interaction, by providing a "login_hint" property. To try this, comment the + // * to make request for tokens without interaction, by providing a "login_hint" property. To try this, comment the // * line above and uncomment the section below. // */ // this.myMSALObj.ssoSilent({loginHint: this.username}) @@ -139,7 +140,7 @@ export class SPAAuthPopup { // this.username = response.account.username; // this.token = response.accessToken; // this.expires = response.expiresOn; - + // // welcomeUser(response.account.username); // // updateTable(response.account); // }).catch(error => { @@ -148,18 +149,17 @@ export class SPAAuthPopup { // this.signIn(); // } // }); - + // let r = await this.myMSALObj.acquireTokenSilent(tokenRequest); // console.log(r); - } + } }) - .catch(error => { + .catch((error) => { console.error(error); }); } signOut() { - /** * You can pass a custom request object below. This will override the initial configuration. For more information, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request @@ -168,13 +168,14 @@ export class SPAAuthPopup { // Choose which account to logout from by passing a username. const logoutRequest = { account: this.myMSALObj.getAccountByUsername(this.username), - mainWindowRedirectUri: '/' + mainWindowRedirectUri: "/", }; this.myMSALObj.logoutPopup(logoutRequest); } - async getToken() { //: Promise { + async getToken() { + //: Promise { if (new Date() < this.expires! && this.token.length > 0) { //return this.token; @@ -184,17 +185,18 @@ export class SPAAuthPopup { this.myMSALObj.setActiveAccount(this.myMSALObj.getAllAccounts()[0]); let r = await this.myMSALObj.acquireTokenSilent(tokenRequest); console.log(r); - } catch(error) { + } catch (error) { if (error instanceof msal.InteractionRequiredAuthError) { this.signIn(); } - }; + } return { - token: this.token, - expire: Number(this.expires), - region: "westus", - endpoint: "/subscriptions/b64471de-f2ac-4075-a3cb-7656bca768d0/resourceGroups/openai_dev/providers/Microsoft.CognitiveServices/accounts/octo-aisystems", - }; + token: this.token, + expire: Number(this.expires), + region: "westus", + endpoint: + "/subscriptions/b64471de-f2ac-4075-a3cb-7656bca768d0/resourceGroups/openai_dev/providers/Microsoft.CognitiveServices/accounts/octo-aisystems", + }; } } diff --git a/ts/packages/shell/src/renderer/src/auth/authRedirect.ts b/ts/packages/shell/src/renderer/src/auth/authRedirect.ts index a19dad403..9a01b625e 100644 --- a/ts/packages/shell/src/renderer/src/auth/authRedirect.ts +++ b/ts/packages/shell/src/renderer/src/auth/authRedirect.ts @@ -7,13 +7,15 @@ import { showWelcomeMessage, updateUI } from "./ui.js"; import { callMSGraph } from "./graph.js"; import { graphConfig } from "./graphConfig.js"; -export type AuthResponseCallback = (response: msal.AuthenticationResult) => void; +export type AuthResponseCallback = ( + response: msal.AuthenticationResult, +) => void; export class SPAAuthRedirect { - private static instance: SPAAuthRedirect; private static initialized: boolean = false; - private static initializedCallbacks: Array = new Array(); + private static initializedCallbacks: Array = + new Array(); public static getInstance = (): SPAAuthRedirect => { if (!SPAAuthRedirect.instance) { @@ -21,14 +23,15 @@ export class SPAAuthRedirect { } return SPAAuthRedirect.instance; - } + }; public static IsInitialized(): boolean { return SPAAuthRedirect.initialized; } - public static registerInitializationCallback(callback: AuthResponseCallback) { - + public static registerInitializationCallback( + callback: AuthResponseCallback, + ) { if (SPAAuthRedirect.initialized) { throw new Error("Authentication already initialized"); } @@ -54,7 +57,7 @@ export class SPAAuthRedirect { } else { this.signOut(); } - } + }; await this.myMSALObj.initialize(); @@ -63,31 +66,31 @@ export class SPAAuthRedirect { * response returned from redirect flow. For more information, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/acquire-token.md */ - this.myMSALObj.handleRedirectPromise() - .then((response) => { - if (response !== null) { - console.log(`Logged in as ${response.account.username}`); - this.username = response.account.username; - this.token = response.accessToken; - this.expires = response.expiresOn; - showWelcomeMessage(this.username); - - // invoke callbacks - } else { - this.selectAccount(); - } + this.myMSALObj + .handleRedirectPromise() + .then((response) => { + if (response !== null) { + console.log(`Logged in as ${response.account.username}`); + this.username = response.account.username; + this.token = response.accessToken; + this.expires = response.expiresOn; + showWelcomeMessage(this.username); + + // invoke callbacks + } else { + this.selectAccount(); + } - SPAAuthRedirect.initialized = true; - }) - .catch((error) => { - console.error(error); - }); + SPAAuthRedirect.initialized = true; + }) + .catch((error) => { + console.error(error); + }); } selectAccount() { - /** - * See here for more info on account retrieval: + * See here for more info on account retrieval: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md */ @@ -106,7 +109,6 @@ export class SPAAuthRedirect { } signIn() { - /** * You can pass a custom request object below. This will override the initial configuration. For more information, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request @@ -116,7 +118,6 @@ export class SPAAuthRedirect { } signOut() { - /** * You can pass a custom request object below. This will override the initial configuration. For more information, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request @@ -132,49 +133,61 @@ export class SPAAuthRedirect { getTokenRedirect(request) { /** - * See here for more info on account retrieval: + * See here for more info on account retrieval: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md */ request.account = this.myMSALObj.getAccountByUsername(this.username); - return this.myMSALObj.acquireTokenSilent(request) - .catch(error => { - console.warn("silent token acquisition fails. acquiring token using redirect"); - if (error instanceof msal.InteractionRequiredAuthError) { - // fallback to interaction when silent call fails - return this.myMSALObj.acquireTokenRedirect(request); - } else { - console.warn(error); - } + return this.myMSALObj.acquireTokenSilent(request).catch((error) => { + console.warn( + "silent token acquisition fails. acquiring token using redirect", + ); + if (error instanceof msal.InteractionRequiredAuthError) { + // fallback to interaction when silent call fails + return this.myMSALObj.acquireTokenRedirect(request); + } else { + console.warn(error); + } - return; - }); + return; + }); } seeProfile() { this.getTokenRedirect(loginRequest) - .then(response => { - callMSGraph(graphConfig.graphMeEndpoint, response!.accessToken, updateUI); - }).catch(error => { + .then((response) => { + callMSGraph( + graphConfig.graphMeEndpoint, + response!.accessToken, + updateUI, + ); + }) + .catch((error) => { console.error(error); }); } readMail() { this.getTokenRedirect(tokenRequest) - .then(response => { - callMSGraph(graphConfig.graphMailEndpoint, response!.accessToken, updateUI); - }).catch(error => { + .then((response) => { + callMSGraph( + graphConfig.graphMailEndpoint, + response!.accessToken, + updateUI, + ); + }) + .catch((error) => { console.error(error); }); } - public async getToken(): Promise { - + public async getToken(): Promise< + msal.AuthenticationResult | undefined | void + > { if (new Date() < this.expires! && this.token.length > 0) { //return this.token; } - return await this.getTokenRedirect(tokenRequest) + return await this.getTokenRedirect(tokenRequest); } } diff --git a/ts/packages/shell/src/renderer/src/auth/graph.ts b/ts/packages/shell/src/renderer/src/auth/graph.ts index 5c3e95142..40a77398f 100644 --- a/ts/packages/shell/src/renderer/src/auth/graph.ts +++ b/ts/packages/shell/src/renderer/src/auth/graph.ts @@ -1,10 +1,10 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -/** +/** * Helper function to call MS Graph API endpoint * using the authorization bearer token scheme -*/ + */ export function callMSGraph(endpoint, token, callback) { const headers = new Headers(); const bearer = `Bearer ${token}`; @@ -13,13 +13,13 @@ export function callMSGraph(endpoint, token, callback) { const options = { method: "GET", - headers: headers + headers: headers, }; - console.log('request made to Graph API at: ' + new Date().toString()); + console.log("request made to Graph API at: " + new Date().toString()); fetch(endpoint, options) - .then(response => response.json()) - .then(response => callback(response, endpoint)) - .catch(error => console.log(error)); + .then((response) => response.json()) + .then((response) => callback(response, endpoint)) + .catch((error) => console.log(error)); } diff --git a/ts/packages/shell/src/renderer/src/auth/graphConfig.ts b/ts/packages/shell/src/renderer/src/auth/graphConfig.ts index 74f5dac4a..382e558fa 100644 --- a/ts/packages/shell/src/renderer/src/auth/graphConfig.ts +++ b/ts/packages/shell/src/renderer/src/auth/graphConfig.ts @@ -4,5 +4,5 @@ // Add here the endpoints for MS Graph API services you would like to use. export const graphConfig = { graphMeEndpoint: "https://graph.microsoft.com/v1.0/me", - graphMailEndpoint: "https://graph.microsoft.com/v1.0/me/messages" + graphMailEndpoint: "https://graph.microsoft.com/v1.0/me/messages", }; diff --git a/ts/packages/shell/src/renderer/src/auth/ui.ts b/ts/packages/shell/src/renderer/src/auth/ui.ts index 8dde7c6d7..ba9e954e8 100644 --- a/ts/packages/shell/src/renderer/src/auth/ui.ts +++ b/ts/packages/shell/src/renderer/src/auth/ui.ts @@ -13,60 +13,70 @@ const profileDiv = document.getElementById("profile-div"); export function showWelcomeMessage(username) { // Reconfiguring DOM elements - cardDiv!.style.display = 'initial'; + cardDiv!.style.display = "initial"; welcomeDiv!.innerHTML = `Welcome ${username}`; -// signInButton!.setAttribute("onclick", "signOut();"); - signInButton!.setAttribute('class', "btn btn-success") + // signInButton!.setAttribute("onclick", "signOut();"); + signInButton!.setAttribute("class", "btn btn-success"); signInButton!.innerHTML = "Sign Out"; } export function updateUI(data, endpoint) { - console.log('Graph API responded at: ' + new Date().toString()); + console.log("Graph API responded at: " + new Date().toString()); if (endpoint === graphConfig.graphMeEndpoint) { - profileDiv!.innerHTML = '' - const title = document.createElement('p'); + profileDiv!.innerHTML = ""; + const title = document.createElement("p"); title.innerHTML = "Title: " + data.jobTitle; - const email = document.createElement('p'); + const email = document.createElement("p"); email.innerHTML = "Mail: " + data.mail; - const phone = document.createElement('p'); + const phone = document.createElement("p"); phone.innerHTML = "Phone: " + data.businessPhones[0]; - const address = document.createElement('p'); + const address = document.createElement("p"); address.innerHTML = "Location: " + data.officeLocation; profileDiv!.appendChild(title); profileDiv!.appendChild(email); profileDiv!.appendChild(phone); profileDiv!.appendChild(address); - } else if (endpoint === graphConfig.graphMailEndpoint) { if (!data.value) { - alert("You do not have a mailbox!") + alert("You do not have a mailbox!"); } else if (data.value.length < 1) { - alert("Your mailbox is empty!") + alert("Your mailbox is empty!"); } else { const tabContent = document.getElementById("nav-tabContent"); const tabList = document.getElementById("list-tab"); - tabList!.innerHTML = ''; // clear tabList at each readMail call + tabList!.innerHTML = ""; // clear tabList at each readMail call data.value.map((d, i) => { // Keeping it simple if (i < 10) { const listItem = document.createElement("a"); - listItem.setAttribute("class", "list-group-item list-group-item-action") - listItem.setAttribute("id", "list" + i + "list") - listItem.setAttribute("data-toggle", "list") - listItem.setAttribute("href", "#list" + i) - listItem.setAttribute("role", "tab") - listItem.setAttribute("aria-controls", i) + listItem.setAttribute( + "class", + "list-group-item list-group-item-action", + ); + listItem.setAttribute("id", "list" + i + "list"); + listItem.setAttribute("data-toggle", "list"); + listItem.setAttribute("href", "#list" + i); + listItem.setAttribute("role", "tab"); + listItem.setAttribute("aria-controls", i); listItem.innerHTML = d.subject; - tabList!.appendChild(listItem) + tabList!.appendChild(listItem); const contentItem = document.createElement("div"); - contentItem.setAttribute("class", "tab-pane fade") - contentItem.setAttribute("id", "list" + i) - contentItem.setAttribute("role", "tabpanel") - contentItem.setAttribute("aria-labelledby", "list" + i + "list") - contentItem.innerHTML = " from: " + d.from.emailAddress.address + "

" + d.bodyPreview + "..."; + contentItem.setAttribute("class", "tab-pane fade"); + contentItem.setAttribute("id", "list" + i); + contentItem.setAttribute("role", "tabpanel"); + contentItem.setAttribute( + "aria-labelledby", + "list" + i + "list", + ); + contentItem.innerHTML = + " from: " + + d.from.emailAddress.address + + "

" + + d.bodyPreview + + "..."; tabContent!.appendChild(contentItem); } }); diff --git a/ts/packages/shell/src/renderer/src/azureSpeech.ts b/ts/packages/shell/src/renderer/src/azureSpeech.ts index 5c7ede08b..9a7ff5e44 100644 --- a/ts/packages/shell/src/renderer/src/azureSpeech.ts +++ b/ts/packages/shell/src/renderer/src/azureSpeech.ts @@ -24,7 +24,7 @@ const IdentityApiKey = "identity"; export class AzureSpeech { private static instance: AzureSpeech; private token: string = ""; - public static IsInitialized(): boolean { + public static IsInitialized(): boolean { return AzureSpeech.instance !== undefined; } @@ -90,7 +90,7 @@ export class AzureSpeech { }; // private getIdentityBasedTokenAsync = async (): Promise => { - // const tokenResult: Result = + // const tokenResult: Result = // success("sdlf"); //await azureTokenProvider.getAccessToken(); // if (!tokenResult.success) { @@ -109,7 +109,6 @@ export class AzureSpeech { // }; public getBrowserTokenAsync = async (): Promise => { - // let silent: msal.SsoSilentRequest = msal.SsoSilentRequest. // authProvider.ssoSilent(new msal.sso). // then((response) => { @@ -118,7 +117,7 @@ export class AzureSpeech { // region: this.region, // endpoint: this.endpoint, // }; - + // return result; // }).catch(error => { // console.error("Silent Error: " + error); @@ -128,7 +127,7 @@ export class AzureSpeech { // }); //const loginResult: msal.AuthenticationResult | undefined | void = await SPAAuthRedirect.getInstance().getToken(); - + // if (loginResult) { // const result: TokenResponse = { // token: loginResult.accessToken, @@ -139,9 +138,8 @@ export class AzureSpeech { // return result; // } - + // return { token: "", expire: Date.now(), region: this.region, endpoint: this.endpoint}; - return new Promise(async (resolve) => { resolve(await SPAAuthPopup.getInstance().getToken()); diff --git a/ts/packages/shell/src/renderer/src/main.ts b/ts/packages/shell/src/renderer/src/main.ts index 20fe34644..166afed55 100644 --- a/ts/packages/shell/src/renderer/src/main.ts +++ b/ts/packages/shell/src/renderer/src/main.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -/// +/// import { ClientAPI, NotifyCommands } from "../../preload/electronTypes"; import { ChatView } from "./chatView"; @@ -204,7 +204,6 @@ function addEvents( }, ); api.onTakeAction((_, action: string, data?: unknown) => { - // Android object gets injected on Android devices, otherwise unavailable try { //Android?.showToast("woohooo 2!"); @@ -220,7 +219,6 @@ function addEvents( return; } } - } catch (e) { console.log(e); } @@ -311,10 +309,11 @@ document.addEventListener("DOMContentLoaded", async function () { const agents = new Map(); // setup SPA (login) - const loginButton: HTMLButtonElement = document.getElementById("SignIn") as HTMLButtonElement; + const loginButton: HTMLButtonElement = document.getElementById( + "SignIn", + ) as HTMLButtonElement; //SPAAuthRedirect.getInstance().initalize(loginButton); SPAAuthPopup.getInstance().initalize(loginButton); - const tabs = new TabView( ["Settings", "Metrics", "Help"], diff --git a/ts/packages/shell/src/renderer/src/webSocketAPI.ts b/ts/packages/shell/src/renderer/src/webSocketAPI.ts index 81d8c6ecf..3da8f7aaf 100644 --- a/ts/packages/shell/src/renderer/src/webSocketAPI.ts +++ b/ts/packages/shell/src/renderer/src/webSocketAPI.ts @@ -173,14 +173,14 @@ export const webapi: ClientAPI = { // TODO: implement client side token acquisition // Depends on implementing client side EntraID Auth first return new Promise(async (resolve) => { - // TODO: get from node instance from now - in the future get form users datastore // intialize speech if (!AzureSpeech.IsInitialized()) { await AzureSpeech.initializeAsync({ azureSpeechSubscriptionKey: "identity", azureSpeechRegion: "westus", - azureSpeechEndpoint: "/subscriptions/b64471de-f2ac-4075-a3cb-7656bca768d0/resourceGroups/openai_dev/providers/Microsoft.CognitiveServices/accounts/octo-aisystems", + azureSpeechEndpoint: + "/subscriptions/b64471de-f2ac-4075-a3cb-7656bca768d0/resourceGroups/openai_dev/providers/Microsoft.CognitiveServices/accounts/octo-aisystems", }); } @@ -194,9 +194,9 @@ export const webapi: ClientAPI = { region: AzureSpeech.getInstance().Region, endpoint: AzureSpeech.getInstance().Endpoint, }; - + resolve(result); - }) + }); } else { resolve(await AzureSpeech.getInstance().getBrowserTokenAsync()); } @@ -293,7 +293,11 @@ export async function createWebSocket( fnMap.get("clear")(undefined, msgObj.data); break; case "take-action": - fnMap.get("take-action")(undefined, msgObj.data.action, msgObj.data.data); + fnMap.get("take-action")( + undefined, + msgObj.data.action, + msgObj.data.data, + ); break; case "notify": notify(msgObj); diff --git a/ts/packages/shell/tsconfig.node.json b/ts/packages/shell/tsconfig.node.json index 5a41a4dc7..c44b3ec16 100644 --- a/ts/packages/shell/tsconfig.node.json +++ b/ts/packages/shell/tsconfig.node.json @@ -1,6 +1,11 @@ { "extends": "@electron-toolkit/tsconfig/tsconfig.node.json", - "include": ["electron.vite.config.*", "src/main/*", "src/preload/*", "src/renderer/src/azurespeech.ts"], + "include": [ + "electron.vite.config.*", + "src/main/*", + "src/preload/*", + "src/renderer/src/azurespeech.ts" + ], "compilerOptions": { "module": "node16", "moduleResolution": "node16",