Skip to main content
Glama
projectAccessKey.controller.ts6.36 kB
import type { ResponseWithSession } from '@middlewares/sessionAuth.middleware'; import { sendEmail } from '@services/email.service'; import * as projectAccessKeyService from '@services/projectAccessKey.service'; import { type AppError, ErrorHandler } from '@utils/errors'; import { hasPermission, intersectPermissions } from '@utils/permissions'; import { formatResponse, type ResponseData } from '@utils/responseData'; import type { NextFunction, Request } from 'express'; import { t } from 'express-intlayer'; import type { AccessKeyData, OAuth2Access } from '@/types/project.types'; export type AddNewAccessKeyBody = AccessKeyData; export type AddNewAccessKeyResponse = ResponseData<OAuth2Access>; /** * Adds a new access key to a project. */ export const addNewAccessKey = async ( req: Request<AddNewAccessKeyBody>, res: ResponseWithSession<AddNewAccessKeyResponse>, _next: NextFunction ): Promise<void> => { const { user, project, roles, permissions } = res.locals; const { grants, name, expiresAt } = req.body; if (!project) { ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED'); return; } if (!user) { ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED'); return; } if ( !hasPermission( roles, 'project:write' )({ ...res.locals, targetProjectIds: [project.id], }) ) { ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED'); return; } const filteredPermisions = intersectPermissions(permissions, grants); try { const newAccessKey = await projectAccessKeyService.addNewAccessKey( { name, expiresAt, grants: filteredPermisions, }, project.id, user ); const responseData = formatResponse<OAuth2Access>({ message: t({ en: 'Access key created successfully', es: 'Clave de acceso creada con éxito', fr: "Clé d'accès créée avec succès", }), description: t({ en: 'The access key has been created successfully', es: 'La clave de acceso ha sido creada con éxito', fr: "La clé d'accès a été créée avec succès", }), data: newAccessKey, }); res.json(responseData); sendEmail({ type: 'oAuthTokenCreated', to: user.email, username: user.name, applicationName: newAccessKey.name ?? newAccessKey.clientId, scopes: newAccessKey.grants, tokenDetailsUrl: `${process.env.CLIENT_URL}/oauth2/token`, securityLogUrl: `${process.env.CLIENT_URL}/security-log`, supportUrl: `${process.env.CLIENT_URL}/support`, }); return; } catch (error) { ErrorHandler.handleAppErrorResponse(res, error as AppError); return; } }; export type DeleteAccessKeyBody = { clientId: string }; export type DeleteAccessKeyResponse = ResponseData<null>; /** * Deletes an access key from a project. */ export const deleteAccessKey = async ( req: Request, res: ResponseWithSession<AddNewAccessKeyResponse>, _next: NextFunction ): Promise<void> => { const { user, project, roles } = res.locals; const { clientId } = req.body; if (!project) { ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED'); return; } if (!user) { ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED'); return; } if (!clientId) { ErrorHandler.handleGenericErrorResponse(res, 'CLIENT_ID_NOT_FOUND'); return; } if ( !hasPermission( roles, 'project:write' )({ ...res.locals, targetProjectIds: [project.id], }) ) { ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED'); return; } try { const deletedAccessKey = await projectAccessKeyService.deleteAccessKey( clientId, project, user.id ); if (!deletedAccessKey) { ErrorHandler.handleGenericErrorResponse(res, 'ACCESS_KEY_NOT_FOUND', { clientId, }); return; } const responseData = formatResponse<null>({ message: t({ en: 'Access key deleted successfully', es: 'Clave de acceso eliminada con éxito', fr: "Clé d'accès supprimée avec succès", }), description: t({ en: 'The access key has been deleted successfully', es: 'La clave de acceso ha sido eliminada con éxito', fr: "La clé d'accès a été supprimée avec succès", }), data: null, }); res.json(responseData); return; } catch (error) { ErrorHandler.handleAppErrorResponse(res, error as AppError); return; } }; export type RefreshAccessKeyBody = { clientId: string }; export type RefreshAccessKeyResponse = ResponseData<OAuth2Access>; /** * Refreshes an access key from a project. */ export const refreshAccessKey = async ( req: Request<RefreshAccessKeyBody>, res: ResponseWithSession<RefreshAccessKeyResponse>, _next: NextFunction ): Promise<void> => { const { user, project, roles } = res.locals; const { clientId } = req.body; if (!project) { ErrorHandler.handleGenericErrorResponse(res, 'PROJECT_NOT_DEFINED'); } if (!user) { ErrorHandler.handleGenericErrorResponse(res, 'USER_NOT_DEFINED'); } if (!clientId) { ErrorHandler.handleGenericErrorResponse(res, 'CLIENT_ID_NOT_FOUND'); } if ( !hasPermission( roles, 'project:write' )({ ...res.locals, targetProjectIds: [project?.id], }) ) { ErrorHandler.handleGenericErrorResponse(res, 'PERMISSION_DENIED'); return; } try { const newAccessKey = await projectAccessKeyService.refreshAccessKey( clientId, project?.id, user?.id ); const responseData = formatResponse<OAuth2Access>({ message: t({ en: 'Access key refreshed successfully', es: 'Clave de acceso actualizada con éxito', fr: "Clé d'accès actualisée avec succès", }), description: t({ en: 'The access key has been refreshed successfully', es: 'La clave de acceso ha sido actualizada con éxito', fr: "La clé d'accès a été actualisée avec succès", }), data: newAccessKey, }); res.json(responseData); return; } catch (error) { ErrorHandler.handleAppErrorResponse(res, error as AppError); return; } };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server