Skip to content

Commit

Permalink
Add Capella iQ Supplemental terms dialog box (#360)
Browse files Browse the repository at this point in the history
Added a dialog box for the "Accept iQ Supplemental terms" so that the
org owner is able to review and accept before proceeding to login. If
the user is not a org owner, the user will be asked to check with the
org owner and logged out.
  • Loading branch information
prajwal-pai77 authored Mar 27, 2024
1 parent 9d00d6c commit 7f6aa1b
Show file tree
Hide file tree
Showing 8 changed files with 548 additions and 184 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vscode-couchbase",
"displayName": "Couchbase",
"description": "",
"version": "1.2.2",
"version": "1.2.3",
"engines": {
"vscode": "^1.63.1"
},
Expand Down
267 changes: 185 additions & 82 deletions src/commands/iq/couchbaseIqWebviewProvider.ts

Large diffs are not rendered by default.

153 changes: 118 additions & 35 deletions src/commands/iq/iqLoginhandler.ts
Original file line number Diff line number Diff line change
@@ -1,106 +1,189 @@
import { Constants } from "../../util/constants";
import { Global, Memory } from "../../util/util";
import { iqRestApiService } from "./iqRestApiService";
import * as keytar from 'keytar';
import * as keytar from "keytar";

interface IFormData {
username: string;
password: string;
rememberMe: boolean;
}

type User = {
id: string;
roles: string[];
};

export interface ISavedLoginDataGetter {
doesLoginDetailsExists: boolean;
username: string
username: string;
}

const getSessionsJwt = async (formData: IFormData): Promise<string> => {
try {
return await iqRestApiService.capellaLogin(formData.username, formData.password);
return await iqRestApiService.capellaLogin(
formData.username,
formData.password
);
} catch (error: any) {
throw new Error(error.message.toString());
}
};


export const iqLoginHandler = async (formData: IFormData) => {
try {
// Check for remember me
// Check for remember me
if (formData.rememberMe === true) {
Global.state.update(Constants.IQ_USER_ID, formData.username);
keytar.setPassword(Constants.IQ_PASSWORD, formData.username, formData.password);
keytar.setPassword(
Constants.IQ_PASSWORD,
formData.username,
formData.password
);
}

// Return organization select page data
const jwtToken = await getSessionsJwt(formData);
Memory.state.update("vscode-couchbase.iq.jwtToken", jwtToken);
const organizations = await iqRestApiService.loadOrganizations(jwtToken);
const organizations = await iqRestApiService.loadOrganizations(
jwtToken
);
return organizations;
} catch(error: any){
} catch (error: any) {
throw new Error(error.message.toString());
}
};

export const iqSavedLoginDataGetter = async (): Promise<ISavedLoginDataGetter> => {
const username = Global.state.get<string>(Constants.IQ_USER_ID);
if (username && username !== "") {
// Username exists, sending it back to webview
return {
doesLoginDetailsExists: true,
username: username
};
} else {
return {
doesLoginDetailsExists: false,
username: ""
};
}
};
export const iqSavedLoginDataGetter =
async (): Promise<ISavedLoginDataGetter> => {
const username = Global.state.get<string>(Constants.IQ_USER_ID);
if (username && username !== "") {
// Username exists, sending it back to webview
return {
doesLoginDetailsExists: true,
username: username,
};
} else {
return {
doesLoginDetailsExists: false,
username: "",
};
}
};

export const iqSavedLoginHandler = async (username: string) => {
try {
const password = await keytar.getPassword(Constants.IQ_PASSWORD, username);
const password = await keytar.getPassword(
Constants.IQ_PASSWORD,
username
);
if (password) {
// Return organization select page data
const jwtToken = await getSessionsJwt({
username: username,
password: password,
rememberMe: true
rememberMe: true,
});
Memory.state.update("vscode-couchbase.iq.jwtToken", jwtToken);
const organizations = await iqRestApiService.loadOrganizations(jwtToken);
const organizations = await iqRestApiService.loadOrganizations(
jwtToken
);
return organizations;
} else {
return undefined;
}
} catch(error: any) {
} catch (error: any) {
throw new Error(error.message.toString());
}
};

export const handleIqSupplementalTerms = async (
orgDetails: any
): Promise<any> => {
const jwtToken = Memory.state.get<string>("vscode-couchbase.iq.jwtToken");
if (jwtToken === undefined) {
return {
isOrgVerified: false,
errorMessage: "",
};
}
if (!orgDetails.iq.other) {
orgDetails.iq.other = {};
}
// Set the isTermsAcceptedForOrg to True
orgDetails.iq.other.isTermsAcceptedForOrg = true;
const response = await iqRestApiService.acceptIqSupplementalTerms(
jwtToken,
orgDetails.id,
orgDetails
);
};

export const checkIfUserIsOrgOwner = async (
userId: string,
user: User
): Promise<boolean> => {
if (user.id === userId) {
return user.roles.includes("organizationOwner");
}
return false;
};

export const verifyOrganization = async (orgId: string): Promise<any> => {
const jwtToken = Memory.state.get<string>("vscode-couchbase.iq.jwtToken");
if (jwtToken === undefined) {
return {
shouldAcceptIqTerms: false,
isOrgVerified: false,
errorMessage: ""
errorMessage: "",
};
}
const orgDetails = await iqRestApiService.getOrganizationDetails(jwtToken, orgId);
if (!orgDetails.iq || orgDetails.iq.enabled === false) {
const orgDetails = await iqRestApiService.getOrganizationDetails(
jwtToken,
orgId
);
const userId = Memory.state.get<string>("vscode-couchbase.iq.userId");
if (userId === undefined) {
return {
shouldAcceptIqTerms: false,
isOrgVerified: false,
errorMessage: `Capella iQ is not enabled for this organization, Please enable it on cloud.couchbase.com`
errorMessage: "",
};
}
if (orgDetails.iq.other.isTermsAcceptedForOrg === false) {
if (!orgDetails.iq || orgDetails.iq.enabled === false) {
return {
shouldAcceptIqTerms: false,
isOrgVerified: false,
errorMessage: `Terms and conditions to use Capella iQ are not accepted for this organization, Please accept it on cloud.couchbase.com`
errorMessage: `Capella iQ is not enabled for this organization, Please enable it on cloud.couchbase.com`,
};
}
if (
!orgDetails.iq.other ||
orgDetails.iq.other.isTermsAcceptedForOrg === false
) {
const userList = await iqRestApiService.fetchUserData(
jwtToken,
orgId,
userId
);
// Allow to Accept Terms ONLY if user is org owner
if (await checkIfUserIsOrgOwner(userId, userList)) {
return {
shouldAcceptIqTerms: true,
isOrgVerified: false,
errorMessage: `Capella iQ uses a third-party large language model (LLM). Please do not enter sensitive data into iQ and review its output before using. `,
};
} else {
return {
shouldAcceptIqTerms: false,
isOrgVerified: false,
errorMessage: `Capella iQ Supplemental Terms have not yet been accepted. To continue, kindly request the organization owner to review and agree to the terms and conditions. `,
};
}
}
return {
shouldAcceptIqTerms: false,
isOrgVerified: true,
errorMessage: ""
errorMessage: "",
};
};
};
Loading

0 comments on commit 7f6aa1b

Please sign in to comment.