mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-19 12:40:09 +01:00
29df483a27
* initial commit for chrome extension * wip browser extension backend * wip frontend browser extension settings * fix typo for browserExtension route * implement verification codes + frontend panel for browser extension keys * reorganize + state management for all connection states * implement embed to workspace * add send page to anythingllm extension option + refactor * refactor connection string auth + update context menus + organize background.js into models * popup extension from main app and save if successful * fix hebrew translation misspelling * fetch custom logo inside chrome extension * delete api keys on disconnect of extension * use correct apiUrl constant in frontend + remove unneeded comments * remove upload-link endpoint and send inner text html to raw text collector endpoint * update readme * fix readme link * fix readme typo * update readme * handle deletion of browser keys with key id and DELETE endpoint * move event string to constant * remove tablename and writable fields from BrowserExtensionApiKey backend model * add border-none to all buttons and inputs for desktop compatibility * patch prisma injections * update delete endpoints to delete keys by id * remove unused prop * add button to attempt browser extension connection + remove max active keys * wip multi user mode support * multi user mode support * clean up backend + show created by in frotend browser extension page * show multi user warning message on key creation + hide context menus when no workspaces * show browser extension options to managers * small backend changes and refactors * extension cleanup * rename submodule * extension updates & docs * dev docker build --------- Co-authored-by: shatfield4 <seanhatfield5@gmail.com>
169 lines
4.9 KiB
JavaScript
169 lines
4.9 KiB
JavaScript
const prisma = require("../utils/prisma");
|
|
const { SystemSettings } = require("./systemSettings");
|
|
const { ROLES } = require("../utils/middleware/multiUserProtected");
|
|
|
|
const BrowserExtensionApiKey = {
|
|
/**
|
|
* Creates a new secret for a browser extension API key.
|
|
* @returns {string} brx-*** API key to use with extension
|
|
*/
|
|
makeSecret: () => {
|
|
const uuidAPIKey = require("uuid-apikey");
|
|
return `brx-${uuidAPIKey.create().apiKey}`;
|
|
},
|
|
|
|
/**
|
|
* Creates a new api key for the browser Extension
|
|
* @param {number|null} userId - User id to associate creation of key with.
|
|
* @returns {Promise<{apiKey: import("@prisma/client").browser_extension_api_keys|null, error:string|null}>}
|
|
*/
|
|
create: async function (userId = null) {
|
|
try {
|
|
const apiKey = await prisma.browser_extension_api_keys.create({
|
|
data: {
|
|
key: this.makeSecret(),
|
|
user_id: userId,
|
|
},
|
|
});
|
|
return { apiKey, error: null };
|
|
} catch (error) {
|
|
console.error("Failed to create browser extension API key", error);
|
|
return { apiKey: null, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Validated existing API key
|
|
* @param {string} key
|
|
* @returns {Promise<{apiKey: import("@prisma/client").browser_extension_api_keys|boolean}>}
|
|
*/
|
|
validate: async function (key) {
|
|
if (!key.startsWith("brx-")) return false;
|
|
const apiKey = await prisma.browser_extension_api_keys.findUnique({
|
|
where: { key: key.toString() },
|
|
include: { user: true },
|
|
});
|
|
if (!apiKey) return false;
|
|
|
|
const multiUserMode = await SystemSettings.isMultiUserMode();
|
|
if (!multiUserMode) return apiKey; // In single-user mode, all keys are valid
|
|
|
|
// In multi-user mode, check if the key is associated with a user
|
|
return apiKey.user_id ? apiKey : false;
|
|
},
|
|
|
|
/**
|
|
* Fetches browser api key by params.
|
|
* @param {object} clause - Prisma props for search
|
|
* @returns {Promise<{apiKey: import("@prisma/client").browser_extension_api_keys|boolean}>}
|
|
*/
|
|
get: async function (clause = {}) {
|
|
try {
|
|
const apiKey = await prisma.browser_extension_api_keys.findFirst({
|
|
where: clause,
|
|
});
|
|
return apiKey;
|
|
} catch (error) {
|
|
console.error("FAILED TO GET BROWSER EXTENSION API KEY.", error.message);
|
|
return null;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Deletes browser api key by db id.
|
|
* @param {number} id - database id of browser key
|
|
* @returns {Promise<{success: boolean, error:string|null}>}
|
|
*/
|
|
delete: async function (id) {
|
|
try {
|
|
await prisma.browser_extension_api_keys.delete({
|
|
where: { id: parseInt(id) },
|
|
});
|
|
return { success: true, error: null };
|
|
} catch (error) {
|
|
console.error("Failed to delete browser extension API key", error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Gets browser keys by params
|
|
* @param {object} clause
|
|
* @param {number|null} limit
|
|
* @param {object|null} orderBy
|
|
* @returns {Promise<import("@prisma/client").browser_extension_api_keys[]>}
|
|
*/
|
|
where: async function (clause = {}, limit = null, orderBy = null) {
|
|
try {
|
|
const apiKeys = await prisma.browser_extension_api_keys.findMany({
|
|
where: clause,
|
|
...(limit !== null ? { take: limit } : {}),
|
|
...(orderBy !== null ? { orderBy } : {}),
|
|
include: { user: true },
|
|
});
|
|
return apiKeys;
|
|
} catch (error) {
|
|
console.error("FAILED TO GET BROWSER EXTENSION API KEYS.", error.message);
|
|
return [];
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get browser API keys for user
|
|
* @param {import("@prisma/client").users} user
|
|
* @param {object} clause
|
|
* @param {number|null} limit
|
|
* @param {object|null} orderBy
|
|
* @returns {Promise<import("@prisma/client").browser_extension_api_keys[]>}
|
|
*/
|
|
whereWithUser: async function (
|
|
user,
|
|
clause = {},
|
|
limit = null,
|
|
orderBy = null
|
|
) {
|
|
// Admin can view and use any keys
|
|
if ([ROLES.admin].includes(user.role))
|
|
return await this.where(clause, limit, orderBy);
|
|
|
|
try {
|
|
const apiKeys = await prisma.browser_extension_api_keys.findMany({
|
|
where: {
|
|
...clause,
|
|
user_id: user.id,
|
|
},
|
|
include: { user: true },
|
|
...(limit !== null ? { take: limit } : {}),
|
|
...(orderBy !== null ? { orderBy } : {}),
|
|
});
|
|
return apiKeys;
|
|
} catch (error) {
|
|
console.error(error.message);
|
|
return [];
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Updates owner of all DB ids to new admin.
|
|
* @param {number} userId
|
|
* @returns {Promise<void>}
|
|
*/
|
|
migrateApiKeysToMultiUser: async function (userId) {
|
|
try {
|
|
await prisma.browser_extension_api_keys.updateMany({
|
|
where: {
|
|
user_id: null,
|
|
},
|
|
data: {
|
|
user_id: userId,
|
|
},
|
|
});
|
|
console.log("Successfully migrated API keys to multi-user mode");
|
|
} catch (error) {
|
|
console.error("Error migrating API keys to multi-user mode:", error);
|
|
}
|
|
},
|
|
};
|
|
|
|
module.exports = { BrowserExtensionApiKey };
|