mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 00:26:40 +00:00
Fix merge conflicts
This commit is contained in:
@@ -40,6 +40,7 @@ import {
|
|||||||
secret as v2SecretRouter,
|
secret as v2SecretRouter,
|
||||||
workspace as v2WorkspaceRouter,
|
workspace as v2WorkspaceRouter,
|
||||||
serviceTokenData as v2ServiceTokenDataRouter,
|
serviceTokenData as v2ServiceTokenDataRouter,
|
||||||
|
apiKeyData as v2APIKeyDataRouter,
|
||||||
} from './routes/v2';
|
} from './routes/v2';
|
||||||
|
|
||||||
import { getLogger } from './utils/logger';
|
import { getLogger } from './utils/logger';
|
||||||
@@ -98,6 +99,7 @@ app.use('/api/v1/integration-auth', v1IntegrationAuthRouter);
|
|||||||
app.use('/api/v2/workspace', v2WorkspaceRouter);
|
app.use('/api/v2/workspace', v2WorkspaceRouter);
|
||||||
app.use('/api/v2/secret', v2SecretRouter);
|
app.use('/api/v2/secret', v2SecretRouter);
|
||||||
app.use('/api/v2/service-token-data', v2ServiceTokenDataRouter);
|
app.use('/api/v2/service-token-data', v2ServiceTokenDataRouter);
|
||||||
|
app.use('/api/v2/api-key-data', v2APIKeyDataRouter);
|
||||||
|
|
||||||
//* Handle unrouted requests and respond with proper error message as well as status code
|
//* Handle unrouted requests and respond with proper error message as well as status code
|
||||||
app.use((req, res, next)=>{
|
app.use((req, res, next)=>{
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { Request, Response } from 'express';
|
|||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
import { Key } from '../../models';
|
import { Key } from '../../models';
|
||||||
import { findMembership } from '../../helpers/membership';
|
import { findMembership } from '../../helpers/membership';
|
||||||
import { GRANTED } from '../../variables';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add (encrypted) copy of workspace key for workspace with id [workspaceId] for user with
|
* Add (encrypted) copy of workspace key for workspace with id [workspaceId] for user with
|
||||||
@@ -26,9 +25,6 @@ export const uploadKey = async (req: Request, res: Response) => {
|
|||||||
throw new Error('Failed receiver membership validation for workspace');
|
throw new Error('Failed receiver membership validation for workspace');
|
||||||
}
|
}
|
||||||
|
|
||||||
receiverMembership.status = GRANTED;
|
|
||||||
await receiverMembership.save();
|
|
||||||
|
|
||||||
await new Key({
|
await new Key({
|
||||||
encryptedKey: key.encryptedKey,
|
encryptedKey: key.encryptedKey,
|
||||||
nonce: key.nonce,
|
nonce: key.nonce,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from '../../helpers/membership';
|
} from '../../helpers/membership';
|
||||||
import { sendMail } from '../../helpers/nodemailer';
|
import { sendMail } from '../../helpers/nodemailer';
|
||||||
import { SITE_URL } from '../../config';
|
import { SITE_URL } from '../../config';
|
||||||
import { ADMIN, MEMBER, GRANTED, ACCEPTED } from '../../variables';
|
import { ADMIN, MEMBER, ACCEPTED } from '../../variables';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that user is a member of workspace with id [workspaceId]
|
* Check that user is a member of workspace with id [workspaceId]
|
||||||
@@ -175,8 +175,7 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => {
|
|||||||
// already a member of the workspace
|
// already a member of the workspace
|
||||||
const inviteeMembership = await Membership.findOne({
|
const inviteeMembership = await Membership.findOne({
|
||||||
user: invitee._id,
|
user: invitee._id,
|
||||||
workspace: workspaceId,
|
workspace: workspaceId
|
||||||
status: GRANTED
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (inviteeMembership)
|
if (inviteeMembership)
|
||||||
@@ -205,8 +204,7 @@ export const inviteUserToWorkspace = async (req: Request, res: Response) => {
|
|||||||
const m = await new Membership({
|
const m = await new Membership({
|
||||||
user: invitee._id,
|
user: invitee._id,
|
||||||
workspace: workspaceId,
|
workspace: workspaceId,
|
||||||
role: MEMBER,
|
role: MEMBER
|
||||||
status: GRANTED
|
|
||||||
}).save();
|
}).save();
|
||||||
|
|
||||||
await sendMail({
|
await sendMail({
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
deleteWorkspace as deleteWork
|
deleteWorkspace as deleteWork
|
||||||
} from '../../helpers/workspace';
|
} from '../../helpers/workspace';
|
||||||
import { addMemberships } from '../../helpers/membership';
|
import { addMemberships } from '../../helpers/membership';
|
||||||
import { ADMIN, COMPLETED, GRANTED } from '../../variables';
|
import { ADMIN } from '../../variables';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return public keys of members of workspace with id [workspaceId]
|
* Return public keys of members of workspace with id [workspaceId]
|
||||||
@@ -33,13 +33,12 @@ export const getWorkspacePublicKeys = async (req: Request, res: Response) => {
|
|||||||
workspace: workspaceId
|
workspace: workspaceId
|
||||||
}).populate<{ user: IUser }>('user', 'publicKey')
|
}).populate<{ user: IUser }>('user', 'publicKey')
|
||||||
)
|
)
|
||||||
.filter((m) => m.status === COMPLETED || m.status === GRANTED)
|
.map((member) => {
|
||||||
.map((member) => {
|
return {
|
||||||
return {
|
publicKey: member.user.publicKey,
|
||||||
publicKey: member.user.publicKey,
|
userId: member.user._id
|
||||||
userId: member.user._id
|
};
|
||||||
};
|
});
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.setUser({ email: req.user.email });
|
Sentry.setUser({ email: req.user.email });
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
@@ -169,8 +168,7 @@ export const createWorkspace = async (req: Request, res: Response) => {
|
|||||||
await addMemberships({
|
await addMemberships({
|
||||||
userIds: [req.user._id],
|
userIds: [req.user._id],
|
||||||
workspaceId: workspace._id.toString(),
|
workspaceId: workspace._id.toString(),
|
||||||
roles: [ADMIN],
|
roles: [ADMIN]
|
||||||
statuses: [GRANTED]
|
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.setUser({ email: req.user.email });
|
Sentry.setUser({ email: req.user.email });
|
||||||
@@ -335,31 +333,4 @@ export const getWorkspaceServiceTokens = async (
|
|||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
serviceTokens
|
serviceTokens
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
export const getWorkspaceServiceTokenData = async (
|
|
||||||
req: Request,
|
|
||||||
res: Response
|
|
||||||
) => {
|
|
||||||
let serviceTokenData;
|
|
||||||
try {
|
|
||||||
const { workspaceId } = req.query;
|
|
||||||
|
|
||||||
serviceTokenData = await ServiceTokenData
|
|
||||||
.find({
|
|
||||||
workspace: workspaceId
|
|
||||||
})
|
|
||||||
.select('+encryptedKey +iv +tag');
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
Sentry.setUser({ email: req.user.email });
|
|
||||||
Sentry.captureException(err);
|
|
||||||
return res.status(400).send({
|
|
||||||
message: 'Failed to get workspace service token data'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.status(200).send({
|
|
||||||
serviceTokenData
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import { Request, Response } from 'express';
|
||||||
|
import * as Sentry from '@sentry/node';
|
||||||
|
import crypto from 'crypto';
|
||||||
|
import bcrypt from 'bcrypt';
|
||||||
|
import {
|
||||||
|
APIKeyData
|
||||||
|
} from '../../models';
|
||||||
|
import {
|
||||||
|
SALT_ROUNDS
|
||||||
|
} from '../../config';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return API key data for user with id [req.user_id]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getAPIKeyData = async (req: Request, res: Response) => {
|
||||||
|
let apiKeyData;
|
||||||
|
try {
|
||||||
|
apiKeyData = await APIKeyData.find({
|
||||||
|
user: req.user._id
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to get API key data'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
apiKeyData
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new API key data for user with id [req.user._id]
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
*/
|
||||||
|
export const createAPIKeyData = async (req: Request, res: Response) => {
|
||||||
|
let apiKey, apiKeyData;
|
||||||
|
try {
|
||||||
|
const { name, expiresIn } = req.body;
|
||||||
|
|
||||||
|
const secret = crypto.randomBytes(16).toString('hex');
|
||||||
|
const secretHash = await bcrypt.hash(secret, SALT_ROUNDS);
|
||||||
|
|
||||||
|
const expiresAt = new Date();
|
||||||
|
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
|
||||||
|
|
||||||
|
apiKeyData = await new APIKeyData({
|
||||||
|
name,
|
||||||
|
expiresAt,
|
||||||
|
user: req.user._id,
|
||||||
|
secretHash
|
||||||
|
}).save();
|
||||||
|
|
||||||
|
// return api key data without sensitive data
|
||||||
|
apiKeyData = await APIKeyData.findById(apiKeyData._id);
|
||||||
|
|
||||||
|
if (!apiKeyData) throw new Error('Failed to find API key data');
|
||||||
|
|
||||||
|
apiKey = `ak.${apiKeyData._id.toString()}.${secret}`;
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to API key data'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
apiKey,
|
||||||
|
apiKeyData
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete API key data with id [apiKeyDataId].
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const deleteAPIKeyData = async (req: Request, res: Response) => {
|
||||||
|
let apiKeyData;
|
||||||
|
try {
|
||||||
|
const { apiKeyDataId } = req.params;
|
||||||
|
|
||||||
|
apiKeyData = await APIKeyData.findByIdAndDelete(apiKeyDataId);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to delete API key data'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
apiKeyData
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import * as workspaceController from './workspaceController';
|
import * as workspaceController from './workspaceController';
|
||||||
import * as serviceTokenDataController from './serviceTokenDataController';
|
import * as serviceTokenDataController from './serviceTokenDataController';
|
||||||
|
import * as apiKeyDataController from './apiKeyDataController';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
workspaceController,
|
workspaceController,
|
||||||
serviceTokenDataController
|
serviceTokenDataController,
|
||||||
|
apiKeyDataController
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Request, Response } from 'express';
|
|||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
import {
|
import {
|
||||||
Key,
|
Key,
|
||||||
|
ServiceTokenData
|
||||||
} from '../../models';
|
} from '../../models';
|
||||||
import {
|
import {
|
||||||
v2PushSecrets as push,
|
v2PushSecrets as push,
|
||||||
@@ -182,4 +183,30 @@ export const getWorkspaceKey = async (req: Request, res: Response) => {
|
|||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
key
|
key
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
export const getWorkspaceServiceTokenData = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
) => {
|
||||||
|
let serviceTokenData;
|
||||||
|
try {
|
||||||
|
const { workspaceId } = req.query;
|
||||||
|
|
||||||
|
serviceTokenData = await ServiceTokenData
|
||||||
|
.find({
|
||||||
|
workspace: workspaceId
|
||||||
|
})
|
||||||
|
.select('+encryptedKey +iv +tag');
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
Sentry.setUser({ email: req.user.email });
|
||||||
|
Sentry.captureException(err);
|
||||||
|
return res.status(400).send({
|
||||||
|
message: 'Failed to get workspace service token data'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
serviceTokenData
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -14,10 +14,8 @@ import {
|
|||||||
*/
|
*/
|
||||||
const requireSecretSnapshotAuth = ({
|
const requireSecretSnapshotAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses
|
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
@@ -34,8 +32,7 @@ const requireSecretSnapshotAuth = ({
|
|||||||
await validateMembership({
|
await validateMembership({
|
||||||
userId: req.user._id.toString(),
|
userId: req.user._id.toString(),
|
||||||
workspaceId: secretSnapshot.workspace.toString(),
|
workspaceId: secretSnapshot.workspace.toString(),
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
});
|
});
|
||||||
|
|
||||||
req.secretSnapshot = secretSnapshot as any;
|
req.secretSnapshot = secretSnapshot as any;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from '../../../middleware';
|
} from '../../../middleware';
|
||||||
import { query, param } from 'express-validator';
|
import { query, param } from 'express-validator';
|
||||||
import { secretController } from '../../controllers/v1';
|
import { secretController } from '../../controllers/v1';
|
||||||
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../../variables';
|
import { ADMIN, MEMBER } from '../../../variables';
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/:secretId/secret-versions',
|
'/:secretId/secret-versions',
|
||||||
@@ -15,8 +15,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireSecretAuth({
|
requireSecretAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('secretId').exists().trim(),
|
param('secretId').exists().trim(),
|
||||||
query('offset').exists().isInt(),
|
query('offset').exists().isInt(),
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
validateRequest
|
validateRequest
|
||||||
} from '../../../middleware';
|
} from '../../../middleware';
|
||||||
import { param } from 'express-validator';
|
import { param } from 'express-validator';
|
||||||
import { ADMIN, MEMBER, GRANTED } from '../../../variables';
|
import { ADMIN, MEMBER } from '../../../variables';
|
||||||
import { secretSnapshotController } from '../../controllers/v1';
|
import { secretSnapshotController } from '../../controllers/v1';
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
@@ -17,8 +17,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireSecretSnapshotAuth({
|
requireSecretSnapshotAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('secretSnapshotId').exists().trim(),
|
param('secretSnapshotId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
validateRequest
|
validateRequest
|
||||||
} from '../../../middleware';
|
} from '../../../middleware';
|
||||||
import { param, query } from 'express-validator';
|
import { param, query } from 'express-validator';
|
||||||
import { ADMIN, MEMBER, GRANTED } from '../../../variables';
|
import { ADMIN, MEMBER } from '../../../variables';
|
||||||
import { workspaceController } from '../../controllers/v1';
|
import { workspaceController } from '../../controllers/v1';
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
@@ -15,8 +15,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
query('offset').exists().isInt(),
|
query('offset').exists().isInt(),
|
||||||
@@ -31,8 +30,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -43,8 +41,7 @@ router.get(
|
|||||||
'/:workspaceId/logs',
|
'/:workspaceId/logs',
|
||||||
requireAuth,
|
requireAuth,
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
query('offset').exists().isInt(),
|
query('offset').exists().isInt(),
|
||||||
|
|||||||
@@ -3,22 +3,25 @@ import * as Sentry from '@sentry/node';
|
|||||||
import bcrypt from 'bcrypt';
|
import bcrypt from 'bcrypt';
|
||||||
import {
|
import {
|
||||||
User,
|
User,
|
||||||
ServiceTokenData
|
ServiceTokenData,
|
||||||
|
APIKeyData
|
||||||
} from '../models';
|
} from '../models';
|
||||||
import {
|
import {
|
||||||
JWT_AUTH_LIFETIME,
|
JWT_AUTH_LIFETIME,
|
||||||
JWT_AUTH_SECRET,
|
JWT_AUTH_SECRET,
|
||||||
JWT_REFRESH_LIFETIME,
|
JWT_REFRESH_LIFETIME,
|
||||||
JWT_REFRESH_SECRET,
|
JWT_REFRESH_SECRET
|
||||||
SALT_ROUNDS
|
|
||||||
} from '../config';
|
} from '../config';
|
||||||
import {
|
import {
|
||||||
AccountNotFoundError,
|
AccountNotFoundError,
|
||||||
ServiceTokenDataNotFoundError,
|
ServiceTokenDataNotFoundError,
|
||||||
UnauthorizedRequestError,
|
APIKeyDataNotFoundError,
|
||||||
BadRequestError
|
UnauthorizedRequestError
|
||||||
} from '../utils/errors';
|
} from '../utils/errors';
|
||||||
|
|
||||||
|
// TODO 1: check if API key works
|
||||||
|
// TODO 2: optimize middleware
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that auth token value [authTokenValue] falls under one of
|
* Validate that auth token value [authTokenValue] falls under one of
|
||||||
* accepted auth modes [acceptedAuthModes].
|
* accepted auth modes [acceptedAuthModes].
|
||||||
@@ -40,6 +43,9 @@ const validateAuthMode = ({
|
|||||||
case 'st':
|
case 'st':
|
||||||
authMode = 'serviceToken';
|
authMode = 'serviceToken';
|
||||||
break;
|
break;
|
||||||
|
case 'ak':
|
||||||
|
authMode = 'apiKey';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
authMode = 'jwt';
|
authMode = 'jwt';
|
||||||
break;
|
break;
|
||||||
@@ -106,9 +112,11 @@ const getAuthSTDPayload = async ({
|
|||||||
|
|
||||||
// TODO: optimize double query
|
// TODO: optimize double query
|
||||||
serviceTokenData = await ServiceTokenData
|
serviceTokenData = await ServiceTokenData
|
||||||
.findById(TOKEN_IDENTIFIER, 'secretHash expiresAt');
|
.findById(TOKEN_IDENTIFIER, '+secretHash +expiresAt');
|
||||||
|
|
||||||
if (serviceTokenData?.expiresAt && new Date(serviceTokenData.expiresAt) < new Date()) {
|
if (!serviceTokenData) {
|
||||||
|
throw ServiceTokenDataNotFoundError({ message: 'Failed to find service token data' });
|
||||||
|
} else if (serviceTokenData?.expiresAt && new Date(serviceTokenData.expiresAt) < new Date()) {
|
||||||
// case: service token expired
|
// case: service token expired
|
||||||
await ServiceTokenData.findByIdAndDelete(serviceTokenData._id);
|
await ServiceTokenData.findByIdAndDelete(serviceTokenData._id);
|
||||||
throw UnauthorizedRequestError({
|
throw UnauthorizedRequestError({
|
||||||
@@ -116,8 +124,6 @@ const getAuthSTDPayload = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!serviceTokenData) throw ServiceTokenDataNotFoundError({ message: 'Failed to find service token data' });
|
|
||||||
|
|
||||||
const isMatch = await bcrypt.compare(TOKEN_SECRET, serviceTokenData.secretHash);
|
const isMatch = await bcrypt.compare(TOKEN_SECRET, serviceTokenData.secretHash);
|
||||||
if (!isMatch) throw UnauthorizedRequestError({
|
if (!isMatch) throw UnauthorizedRequestError({
|
||||||
message: 'Failed to authenticate service token'
|
message: 'Failed to authenticate service token'
|
||||||
@@ -136,6 +142,50 @@ const getAuthSTDPayload = async ({
|
|||||||
return serviceTokenData;
|
return serviceTokenData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return API key data payload corresponding to API key [authTokenValue]
|
||||||
|
* @param {Object} obj
|
||||||
|
* @param {String} obj.authTokenValue - API key value
|
||||||
|
* @returns {APIKeyData} apiKeyData - API key data
|
||||||
|
*/
|
||||||
|
const getAuthAPIKeyPayload = async ({
|
||||||
|
authTokenValue
|
||||||
|
}: {
|
||||||
|
authTokenValue: string;
|
||||||
|
}) => {
|
||||||
|
let user;
|
||||||
|
try {
|
||||||
|
const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split('.', 3);
|
||||||
|
|
||||||
|
const apiKeyData = await APIKeyData
|
||||||
|
.findById(TOKEN_IDENTIFIER, '+secretHash +expiresAt')
|
||||||
|
.populate('user', '+publicKey');
|
||||||
|
|
||||||
|
if (!apiKeyData) {
|
||||||
|
throw APIKeyDataNotFoundError({ message: 'Failed to find API key data' });
|
||||||
|
} else if (apiKeyData?.expiresAt && new Date(apiKeyData.expiresAt) < new Date()) {
|
||||||
|
// case: API key expired
|
||||||
|
await APIKeyData.findByIdAndDelete(apiKeyData._id);
|
||||||
|
throw UnauthorizedRequestError({
|
||||||
|
message: 'Failed to authenticate expired API key'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const isMatch = await bcrypt.compare(TOKEN_SECRET, apiKeyData.secretHash);
|
||||||
|
if (!isMatch) throw UnauthorizedRequestError({
|
||||||
|
message: 'Failed to authenticate API key'
|
||||||
|
});
|
||||||
|
|
||||||
|
user = apiKeyData.user;
|
||||||
|
} catch (err) {
|
||||||
|
throw UnauthorizedRequestError({
|
||||||
|
message: 'Failed to authenticate API key'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return newly issued (JWT) auth and refresh tokens to user with id [userId]
|
* Return newly issued (JWT) auth and refresh tokens to user with id [userId]
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
@@ -229,6 +279,7 @@ export {
|
|||||||
validateAuthMode,
|
validateAuthMode,
|
||||||
getAuthUserPayload,
|
getAuthUserPayload,
|
||||||
getAuthSTDPayload,
|
getAuthSTDPayload,
|
||||||
|
getAuthAPIKeyPayload,
|
||||||
createToken,
|
createToken,
|
||||||
issueTokens,
|
issueTokens,
|
||||||
clearTokens
|
clearTokens
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Membership, Key } from '../models';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that user with id [userId] is a member of workspace with id [workspaceId]
|
* Validate that user with id [userId] is a member of workspace with id [workspaceId]
|
||||||
* and has at least one of the roles in [acceptedRoles] and statuses in [acceptedStatuses]
|
* and has at least one of the roles in [acceptedRoles]
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @param {String} obj.userId - id of user to validate
|
* @param {String} obj.userId - id of user to validate
|
||||||
* @param {String} obj.workspaceId - id of workspace
|
* @param {String} obj.workspaceId - id of workspace
|
||||||
@@ -12,12 +12,10 @@ const validateMembership = async ({
|
|||||||
userId,
|
userId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses
|
|
||||||
}: {
|
}: {
|
||||||
userId: string;
|
userId: string;
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
let membership;
|
let membership;
|
||||||
@@ -33,11 +31,6 @@ const validateMembership = async ({
|
|||||||
if (!acceptedRoles.includes(membership.role)) {
|
if (!acceptedRoles.includes(membership.role)) {
|
||||||
throw new Error('Failed to validate membership role');
|
throw new Error('Failed to validate membership role');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!acceptedStatuses.includes(membership.status)) {
|
|
||||||
throw new Error('Failed to validate membership status');
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.setUser(null);
|
Sentry.setUser(null);
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
@@ -72,18 +65,15 @@ const findMembership = async (queryObj: any) => {
|
|||||||
* @param {String[]} obj.userIds - id of users.
|
* @param {String[]} obj.userIds - id of users.
|
||||||
* @param {String} obj.workspaceId - id of workspace.
|
* @param {String} obj.workspaceId - id of workspace.
|
||||||
* @param {String[]} obj.roles - roles of users.
|
* @param {String[]} obj.roles - roles of users.
|
||||||
* @param {String[]} obj.statuses - statuses of users.
|
|
||||||
*/
|
*/
|
||||||
const addMemberships = async ({
|
const addMemberships = async ({
|
||||||
userIds,
|
userIds,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
roles,
|
roles
|
||||||
statuses
|
|
||||||
}: {
|
}: {
|
||||||
userIds: string[];
|
userIds: string[];
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
roles: string[];
|
roles: string[];
|
||||||
statuses: string[];
|
|
||||||
}): Promise<void> => {
|
}): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const operations = userIds.map((userId, idx) => {
|
const operations = userIds.map((userId, idx) => {
|
||||||
@@ -92,14 +82,12 @@ const addMemberships = async ({
|
|||||||
filter: {
|
filter: {
|
||||||
user: userId,
|
user: userId,
|
||||||
workspace: workspaceId,
|
workspace: workspaceId,
|
||||||
role: roles[idx],
|
role: roles[idx]
|
||||||
status: statuses[idx]
|
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
user: userId,
|
user: userId,
|
||||||
workspace: workspaceId,
|
workspace: workspaceId,
|
||||||
role: roles[idx],
|
role: roles[idx]
|
||||||
status: statuses[idx]
|
|
||||||
},
|
},
|
||||||
upsert: true
|
upsert: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import rateLimit from 'express-rate-limit';
|
|||||||
// 300 requests per 15 minutes
|
// 300 requests per 15 minutes
|
||||||
const apiLimiter = rateLimit({
|
const apiLimiter = rateLimit({
|
||||||
windowMs: 15 * 60 * 1000,
|
windowMs: 15 * 60 * 1000,
|
||||||
max: 400,
|
max: 450,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
skip: (request) => request.path === '/healthcheck'
|
skip: (request) => request.path === '/healthcheck'
|
||||||
@@ -20,7 +20,7 @@ const signupLimiter = rateLimit({
|
|||||||
// 10 requests per hour
|
// 10 requests per hour
|
||||||
const loginLimiter = rateLimit({
|
const loginLimiter = rateLimit({
|
||||||
windowMs: 60 * 60 * 1000,
|
windowMs: 60 * 60 * 1000,
|
||||||
max: 20,
|
max: 25,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false
|
legacyHeaders: false
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { createOrganization } from './organization';
|
|||||||
import { addMembershipsOrg } from './membershipOrg';
|
import { addMembershipsOrg } from './membershipOrg';
|
||||||
import { createWorkspace } from './workspace';
|
import { createWorkspace } from './workspace';
|
||||||
import { addMemberships } from './membership';
|
import { addMemberships } from './membership';
|
||||||
import { OWNER, ADMIN, ACCEPTED, GRANTED } from '../variables';
|
import { OWNER, ADMIN, ACCEPTED } from '../variables';
|
||||||
import { sendMail } from '../helpers/nodemailer';
|
import { sendMail } from '../helpers/nodemailer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,8 +113,7 @@ const initializeDefaultOrg = async ({
|
|||||||
await addMemberships({
|
await addMemberships({
|
||||||
userIds: [user._id.toString()],
|
userIds: [user._id.toString()],
|
||||||
workspaceId: workspace._id.toString(),
|
workspaceId: workspace._id.toString(),
|
||||||
roles: [ADMIN],
|
roles: [ADMIN]
|
||||||
statuses: [GRANTED]
|
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error('Failed to initialize default organization and workspace');
|
throw new Error('Failed to initialize default organization and workspace');
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { User, ServiceTokenData } from '../models';
|
|||||||
import {
|
import {
|
||||||
validateAuthMode,
|
validateAuthMode,
|
||||||
getAuthUserPayload,
|
getAuthUserPayload,
|
||||||
getAuthSTDPayload
|
getAuthSTDPayload,
|
||||||
|
getAuthAPIKeyPayload
|
||||||
} from '../helpers/auth';
|
} from '../helpers/auth';
|
||||||
import { BadRequestError } from '../utils/errors';
|
import { BadRequestError } from '../utils/errors';
|
||||||
|
|
||||||
@@ -53,6 +54,11 @@ const requireAuth = ({
|
|||||||
authTokenValue: AUTH_TOKEN_VALUE
|
authTokenValue: AUTH_TOKEN_VALUE
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'apiKey':
|
||||||
|
req.user = await getAuthAPIKeyPayload({
|
||||||
|
authTokenValue: AUTH_TOKEN_VALUE
|
||||||
|
});
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
req.user = await getAuthUserPayload({
|
req.user = await getAuthUserPayload({
|
||||||
authTokenValue: AUTH_TOKEN_VALUE
|
authTokenValue: AUTH_TOKEN_VALUE
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ type req = 'params' | 'body' | 'query';
|
|||||||
|
|
||||||
const requireBotAuth = ({
|
const requireBotAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses,
|
|
||||||
location = 'params'
|
location = 'params'
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
|
||||||
location?: req;
|
location?: req;
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
@@ -24,8 +22,7 @@ const requireBotAuth = ({
|
|||||||
await validateMembership({
|
await validateMembership({
|
||||||
userId: req.user._id.toString(),
|
userId: req.user._id.toString(),
|
||||||
workspaceId: bot.workspace.toString(),
|
workspaceId: bot.workspace.toString(),
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
});
|
});
|
||||||
|
|
||||||
req.bot = bot;
|
req.bot = bot;
|
||||||
|
|||||||
@@ -9,14 +9,11 @@ import { IntegrationNotFoundError, UnauthorizedRequestError } from '../utils/err
|
|||||||
* with the integration on request params.
|
* with the integration on request params.
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
||||||
* @param {String[]} obj.acceptedStatuses - accepted workspace statuses
|
|
||||||
*/
|
*/
|
||||||
const requireIntegrationAuth = ({
|
const requireIntegrationAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
// integration authorization middleware
|
// integration authorization middleware
|
||||||
@@ -35,8 +32,7 @@ const requireIntegrationAuth = ({
|
|||||||
await validateMembership({
|
await validateMembership({
|
||||||
userId: req.user._id.toString(),
|
userId: req.user._id.toString(),
|
||||||
workspaceId: integration.workspace.toString(),
|
workspaceId: integration.workspace.toString(),
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const integrationAuth = await IntegrationAuth.findOne({
|
const integrationAuth = await IntegrationAuth.findOne({
|
||||||
|
|||||||
@@ -10,16 +10,13 @@ import { UnauthorizedRequestError } from '../utils/errors';
|
|||||||
* with the integration authorization on request params.
|
* with the integration authorization on request params.
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
||||||
* @param {String[]} obj.acceptedStatuses - accepted workspace statuses
|
|
||||||
* @param {Boolean} obj.attachAccessToken - whether or not to decrypt and attach integration authorization access token onto request
|
* @param {Boolean} obj.attachAccessToken - whether or not to decrypt and attach integration authorization access token onto request
|
||||||
*/
|
*/
|
||||||
const requireIntegrationAuthorizationAuth = ({
|
const requireIntegrationAuthorizationAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses,
|
|
||||||
attachAccessToken = true
|
attachAccessToken = true
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
|
||||||
attachAccessToken?: boolean;
|
attachAccessToken?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
@@ -38,8 +35,7 @@ const requireIntegrationAuthorizationAuth = ({
|
|||||||
await validateMembership({
|
await validateMembership({
|
||||||
userId: req.user._id.toString(),
|
userId: req.user._id.toString(),
|
||||||
workspaceId: integrationAuth.workspace.toString(),
|
workspaceId: integrationAuth.workspace.toString(),
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
});
|
});
|
||||||
|
|
||||||
req.integrationAuth = integrationAuth;
|
req.integrationAuth = integrationAuth;
|
||||||
|
|||||||
@@ -9,15 +9,12 @@ import {
|
|||||||
* Validate if user on request has proper membership to modify secret.
|
* Validate if user on request has proper membership to modify secret.
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
* @param {String[]} obj.acceptedRoles - accepted workspace roles
|
||||||
* @param {String[]} obj.acceptedStatuses - accepted workspace statuses
|
|
||||||
* @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing
|
* @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing
|
||||||
*/
|
*/
|
||||||
const requireSecretAuth = ({
|
const requireSecretAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
try {
|
try {
|
||||||
@@ -34,8 +31,7 @@ const requireSecretAuth = ({
|
|||||||
await validateMembership({
|
await validateMembership({
|
||||||
userId: req.user._id.toString(),
|
userId: req.user._id.toString(),
|
||||||
workspaceId: secret.workspace.toString(),
|
workspaceId: secret.workspace.toString(),
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
});
|
});
|
||||||
|
|
||||||
req.secret = secret as any;
|
req.secret = secret as any;
|
||||||
|
|||||||
@@ -7,11 +7,9 @@ type req = 'params' | 'body' | 'query';
|
|||||||
|
|
||||||
const requireServiceTokenDataAuth = ({
|
const requireServiceTokenDataAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses,
|
|
||||||
location = 'params'
|
location = 'params'
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
|
||||||
location?: req;
|
location?: req;
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
@@ -30,8 +28,7 @@ const requireServiceTokenDataAuth = ({
|
|||||||
await validateMembership({
|
await validateMembership({
|
||||||
userId: req.user._id.toString(),
|
userId: req.user._id.toString(),
|
||||||
workspaceId: serviceTokenData.workspace.toString(),
|
workspaceId: serviceTokenData.workspace.toString(),
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,16 +9,13 @@ type req = 'params' | 'body' | 'query';
|
|||||||
* on request params.
|
* on request params.
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @param {String[]} obj.acceptedRoles - accepted workspace roles for JWT auth
|
* @param {String[]} obj.acceptedRoles - accepted workspace roles for JWT auth
|
||||||
* @param {String[]} obj.acceptedStatuses - accepted workspace statuses for JWT auth
|
|
||||||
* @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing
|
* @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing
|
||||||
*/
|
*/
|
||||||
const requireWorkspaceAuth = ({
|
const requireWorkspaceAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses,
|
|
||||||
location = 'params'
|
location = 'params'
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: string[];
|
||||||
acceptedStatuses: string[];
|
|
||||||
location?: req;
|
location?: req;
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
@@ -30,8 +27,7 @@ const requireWorkspaceAuth = ({
|
|||||||
const membership = await validateMembership({
|
const membership = await validateMembership({
|
||||||
userId: req.user._id.toString(),
|
userId: req.user._id.toString(),
|
||||||
workspaceId,
|
workspaceId,
|
||||||
acceptedRoles,
|
acceptedRoles
|
||||||
acceptedStatuses
|
|
||||||
});
|
});
|
||||||
|
|
||||||
req.membership = membership;
|
req.membership = membership;
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { Schema, model, Types } from 'mongoose';
|
||||||
|
|
||||||
|
export interface IAPIKeyData {
|
||||||
|
name: string;
|
||||||
|
user: Types.ObjectId;
|
||||||
|
expiresAt: Date;
|
||||||
|
secretHash: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiKeyDataSchema = new Schema<IAPIKeyData>(
|
||||||
|
{
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: 'User',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
expiresAt: {
|
||||||
|
type: Date
|
||||||
|
},
|
||||||
|
secretHash: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
select: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const APIKeyData = model<IAPIKeyData>('APIKeyData', apiKeyDataSchema);
|
||||||
|
|
||||||
|
export default APIKeyData;
|
||||||
@@ -14,7 +14,8 @@ import Token, { IToken } from './token';
|
|||||||
import User, { IUser } from './user';
|
import User, { IUser } from './user';
|
||||||
import UserAction, { IUserAction } from './userAction';
|
import UserAction, { IUserAction } from './userAction';
|
||||||
import Workspace, { IWorkspace } from './workspace';
|
import Workspace, { IWorkspace } from './workspace';
|
||||||
import ServiceTokenData, { IServiceTokenData } from './serviceTokenData ';
|
import ServiceTokenData, { IServiceTokenData } from './serviceTokenData';
|
||||||
|
import APIKeyData, { IAPIKeyData } from './apiKeyData';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
BackupPrivateKey,
|
BackupPrivateKey,
|
||||||
@@ -50,5 +51,7 @@ export {
|
|||||||
Workspace,
|
Workspace,
|
||||||
IWorkspace,
|
IWorkspace,
|
||||||
ServiceTokenData,
|
ServiceTokenData,
|
||||||
IServiceTokenData
|
IServiceTokenData,
|
||||||
|
APIKeyData,
|
||||||
|
IAPIKeyData
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Schema, model, Types } from 'mongoose';
|
import { Schema, model, Types } from 'mongoose';
|
||||||
import { ADMIN, MEMBER, INVITED, COMPLETED, GRANTED } from '../variables';
|
import { ADMIN, MEMBER } from '../variables';
|
||||||
|
|
||||||
export interface IMembership {
|
export interface IMembership {
|
||||||
_id: Types.ObjectId;
|
_id: Types.ObjectId;
|
||||||
@@ -7,7 +7,6 @@ export interface IMembership {
|
|||||||
inviteEmail?: string;
|
inviteEmail?: string;
|
||||||
workspace: Types.ObjectId;
|
workspace: Types.ObjectId;
|
||||||
role: 'admin' | 'member';
|
role: 'admin' | 'member';
|
||||||
status: 'invited' | 'completed' | 'granted';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const membershipSchema = new Schema(
|
const membershipSchema = new Schema(
|
||||||
@@ -28,12 +27,6 @@ const membershipSchema = new Schema(
|
|||||||
type: String,
|
type: String,
|
||||||
enum: [ADMIN, MEMBER],
|
enum: [ADMIN, MEMBER],
|
||||||
required: true
|
required: true
|
||||||
},
|
|
||||||
status: {
|
|
||||||
// INVITED, COMPLETED, GRANTED
|
|
||||||
type: String,
|
|
||||||
enum: [INVITED, COMPLETED, GRANTED],
|
|
||||||
required: true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Schema, model, Types } from 'mongoose';
|
import { Schema, model, Types } from 'mongoose';
|
||||||
import { ENV_DEV, ENV_TESTING, ENV_STAGING, ENV_PROD } from '../variables';
|
|
||||||
|
|
||||||
export interface IServiceTokenData {
|
export interface IServiceTokenData {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -38,7 +37,6 @@ const serviceTokenDataSchema = new Schema<IServiceTokenData>(
|
|||||||
},
|
},
|
||||||
secretHash: {
|
secretHash: {
|
||||||
type: String,
|
type: String,
|
||||||
unique: true,
|
|
||||||
required: true,
|
required: true,
|
||||||
select: false
|
select: false
|
||||||
},
|
},
|
||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
validateRequest
|
validateRequest
|
||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
import { botController } from '../../controllers/v1';
|
import { botController } from '../../controllers/v1';
|
||||||
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER } from '../../variables';
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'/:workspaceId',
|
'/:workspaceId',
|
||||||
@@ -16,8 +16,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim().notEmpty(),
|
param('workspaceId').exists().trim().notEmpty(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -30,8 +29,7 @@ router.patch(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireBotAuth({
|
requireBotAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
body('isActive').isBoolean(),
|
body('isActive').isBoolean(),
|
||||||
body('botKey'),
|
body('botKey'),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
requireIntegrationAuth,
|
requireIntegrationAuth,
|
||||||
validateRequest
|
validateRequest
|
||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
import { ADMIN, MEMBER, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER } from '../../variables';
|
||||||
import { body, param } from 'express-validator';
|
import { body, param } from 'express-validator';
|
||||||
import { integrationController } from '../../controllers/v1';
|
import { integrationController } from '../../controllers/v1';
|
||||||
|
|
||||||
@@ -15,8 +15,7 @@ router.patch(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireIntegrationAuth({
|
requireIntegrationAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('integrationId').exists().trim(),
|
param('integrationId').exists().trim(),
|
||||||
body('app').exists().trim(),
|
body('app').exists().trim(),
|
||||||
@@ -35,8 +34,7 @@ router.delete(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireIntegrationAuth({
|
requireIntegrationAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('integrationId').exists().trim(),
|
param('integrationId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
requireIntegrationAuthorizationAuth,
|
requireIntegrationAuthorizationAuth,
|
||||||
validateRequest
|
validateRequest
|
||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
import { ADMIN, MEMBER, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER } from '../../variables';
|
||||||
import { integrationAuthController } from '../../controllers/v1';
|
import { integrationAuthController } from '../../controllers/v1';
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
@@ -25,7 +25,6 @@ router.post(
|
|||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [GRANTED],
|
|
||||||
location: 'body'
|
location: 'body'
|
||||||
}),
|
}),
|
||||||
body('workspaceId').exists().trim().notEmpty(),
|
body('workspaceId').exists().trim().notEmpty(),
|
||||||
@@ -41,8 +40,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireIntegrationAuthorizationAuth({
|
requireIntegrationAuthorizationAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('integrationAuthId'),
|
param('integrationAuthId'),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -56,7 +54,6 @@ router.delete(
|
|||||||
}),
|
}),
|
||||||
requireIntegrationAuthorizationAuth({
|
requireIntegrationAuthorizationAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [GRANTED],
|
|
||||||
attachAccessToken: false
|
attachAccessToken: false
|
||||||
}),
|
}),
|
||||||
param('integrationAuthId'),
|
param('integrationAuthId'),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
validateRequest
|
validateRequest
|
||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
import { body, param } from 'express-validator';
|
import { body, param } from 'express-validator';
|
||||||
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER } from '../../variables';
|
||||||
import { keyController } from '../../controllers/v1';
|
import { keyController } from '../../controllers/v1';
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -15,8 +15,7 @@ router.post(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
body('key').exists(),
|
body('key').exists(),
|
||||||
@@ -30,8 +29,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId'),
|
param('workspaceId'),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
import { body, query, param } from 'express-validator';
|
import { body, query, param } from 'express-validator';
|
||||||
import { secretController } from '../../controllers/v1';
|
import { secretController } from '../../controllers/v1';
|
||||||
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER } from '../../variables';
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
'/:workspaceId',
|
'/:workspaceId',
|
||||||
@@ -16,8 +16,7 @@ router.post(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
body('secrets').exists(),
|
body('secrets').exists(),
|
||||||
body('keys').exists(),
|
body('keys').exists(),
|
||||||
@@ -34,8 +33,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
query('environment').exists().trim(),
|
query('environment').exists().trim(),
|
||||||
query('channel'),
|
query('channel'),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
validateRequest
|
validateRequest
|
||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
import { body } from 'express-validator';
|
import { body } from 'express-validator';
|
||||||
import { ADMIN, MEMBER, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER } from '../../variables';
|
||||||
import { serviceTokenController } from '../../controllers/v1';
|
import { serviceTokenController } from '../../controllers/v1';
|
||||||
|
|
||||||
// note: deprecate service-token routes in favor of service-token data routes/structure
|
// note: deprecate service-token routes in favor of service-token data routes/structure
|
||||||
@@ -25,7 +25,6 @@ router.post(
|
|||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [GRANTED],
|
|
||||||
location: 'body'
|
location: 'body'
|
||||||
}),
|
}),
|
||||||
body('name').exists().trim().notEmpty(),
|
body('name').exists().trim().notEmpty(),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
requireWorkspaceAuth,
|
requireWorkspaceAuth,
|
||||||
validateRequest
|
validateRequest
|
||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER } from '../../variables';
|
||||||
import { workspaceController, membershipController } from '../../controllers/v1';
|
import { workspaceController, membershipController } from '../../controllers/v1';
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
@@ -15,8 +15,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -30,7 +29,6 @@ router.get(
|
|||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -51,8 +49,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -76,8 +73,7 @@ router.delete(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN],
|
acceptedRoles: [ADMIN]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -90,8 +86,7 @@ router.post(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
body('name').exists().trim().notEmpty(),
|
body('name').exists().trim().notEmpty(),
|
||||||
@@ -105,8 +100,7 @@ router.post(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
body('email').exists().trim().notEmpty(),
|
body('email').exists().trim().notEmpty(),
|
||||||
@@ -120,8 +114,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -134,8 +127,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
@@ -148,26 +140,11 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
workspaceController.getWorkspaceServiceTokens
|
workspaceController.getWorkspaceServiceTokens
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get(
|
|
||||||
'/:workspaceId/service-token-data',
|
|
||||||
requireAuth({
|
|
||||||
acceptedAuthModes: ['jwt']
|
|
||||||
}),
|
|
||||||
requireWorkspaceAuth({
|
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
|
||||||
acceptedStatuses: [GRANTED]
|
|
||||||
}),
|
|
||||||
param('workspaceId').exists().trim(),
|
|
||||||
validateRequest,
|
|
||||||
workspaceController.getWorkspaceServiceTokenData
|
|
||||||
);
|
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import express from 'express';
|
||||||
|
const router = express.Router();
|
||||||
|
import {
|
||||||
|
requireAuth,
|
||||||
|
validateRequest
|
||||||
|
} from '../../middleware';
|
||||||
|
import { param, body } from 'express-validator';
|
||||||
|
import { apiKeyDataController } from '../../controllers/v2';
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
'/',
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt']
|
||||||
|
}),
|
||||||
|
apiKeyDataController.getAPIKeyData
|
||||||
|
);
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
'/',
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt']
|
||||||
|
}),
|
||||||
|
body('name').exists().trim(),
|
||||||
|
body('expiresIn'), // measured in ms
|
||||||
|
validateRequest,
|
||||||
|
apiKeyDataController.createAPIKeyData
|
||||||
|
);
|
||||||
|
|
||||||
|
router.delete(
|
||||||
|
'/:apiKeyDataId',
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt']
|
||||||
|
}),
|
||||||
|
param('apiKeyDataId').exists().trim(),
|
||||||
|
validateRequest,
|
||||||
|
apiKeyDataController.deleteAPIKeyData
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
import secret from './secret';
|
import secret from './secret';
|
||||||
import workspace from './workspace';
|
import workspace from './workspace';
|
||||||
import serviceTokenData from './serviceTokenData';
|
import serviceTokenData from './serviceTokenData';
|
||||||
|
import apiKeyData from './apiKeyData';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
secret,
|
secret,
|
||||||
workspace,
|
workspace,
|
||||||
serviceTokenData
|
serviceTokenData,
|
||||||
|
apiKeyData
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import { param, body } from 'express-validator';
|
|||||||
import {
|
import {
|
||||||
ADMIN,
|
ADMIN,
|
||||||
MEMBER,
|
MEMBER,
|
||||||
COMPLETED,
|
|
||||||
GRANTED
|
|
||||||
} from '../../variables';
|
} from '../../variables';
|
||||||
import { serviceTokenDataController } from '../../controllers/v2';
|
import { serviceTokenDataController } from '../../controllers/v2';
|
||||||
|
|
||||||
@@ -30,7 +28,6 @@ router.post(
|
|||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [COMPLETED, GRANTED],
|
|
||||||
location: 'body'
|
location: 'body'
|
||||||
}),
|
}),
|
||||||
body('name').exists().trim(),
|
body('name').exists().trim(),
|
||||||
@@ -50,8 +47,7 @@ router.delete(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireServiceTokenDataAuth({
|
requireServiceTokenDataAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED],
|
|
||||||
}),
|
}),
|
||||||
param('serviceTokenDataId').exists().trim(),
|
param('serviceTokenDataId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
requireWorkspaceAuth,
|
requireWorkspaceAuth,
|
||||||
validateRequest
|
validateRequest
|
||||||
} from '../../middleware';
|
} from '../../middleware';
|
||||||
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER } from '../../variables';
|
||||||
import { workspaceController } from '../../controllers/v2';
|
import { workspaceController } from '../../controllers/v2';
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -15,8 +15,7 @@ router.post(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
body('secrets').exists(),
|
body('secrets').exists(),
|
||||||
body('keys').exists(),
|
body('keys').exists(),
|
||||||
@@ -33,8 +32,7 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt', 'serviceToken']
|
acceptedAuthModes: ['jwt', 'serviceToken']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
query('environment').exists().trim(),
|
query('environment').exists().trim(),
|
||||||
query('channel'),
|
query('channel'),
|
||||||
@@ -49,12 +47,24 @@ router.get(
|
|||||||
acceptedAuthModes: ['jwt']
|
acceptedAuthModes: ['jwt']
|
||||||
}),
|
}),
|
||||||
requireWorkspaceAuth({
|
requireWorkspaceAuth({
|
||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
|
||||||
}),
|
}),
|
||||||
param('workspaceId').exists().trim(),
|
param('workspaceId').exists().trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
workspaceController.getWorkspaceKey
|
workspaceController.getWorkspaceKey
|
||||||
);
|
);
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
'/:workspaceId/service-token-data',
|
||||||
|
requireAuth({
|
||||||
|
acceptedAuthModes: ['jwt']
|
||||||
|
}),
|
||||||
|
requireWorkspaceAuth({
|
||||||
|
acceptedRoles: [ADMIN, MEMBER]
|
||||||
|
}),
|
||||||
|
param('workspaceId').exists().trim(),
|
||||||
|
validateRequest,
|
||||||
|
workspaceController.getWorkspaceServiceTokenData
|
||||||
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
Vendored
+1
@@ -17,6 +17,7 @@ declare global {
|
|||||||
serviceToken: any;
|
serviceToken: any;
|
||||||
accessToken: any;
|
accessToken: any;
|
||||||
serviceTokenData: any;
|
serviceTokenData: any;
|
||||||
|
apiKeyData: any;
|
||||||
query?: any;
|
query?: any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,4 +153,14 @@ export const ServiceTokenDataNotFoundError = (error?: Partial<RequestErrorContex
|
|||||||
stack: error?.stack
|
stack: error?.stack
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//* ----->[API KEY DATA ERRORS]<-----
|
||||||
|
export const APIKeyDataNotFoundError = (error?: Partial<RequestErrorContext>) => new RequestError({
|
||||||
|
logLevel: error?.logLevel ?? LogLevel.ERROR,
|
||||||
|
statusCode: error?.statusCode ?? 404,
|
||||||
|
type: error?.type ?? 'service_token_data_not_found_error',
|
||||||
|
message: error?.message ?? 'The requested service token data was not found',
|
||||||
|
context: error?.context,
|
||||||
|
stack: error?.stack
|
||||||
|
})
|
||||||
|
|
||||||
//* ----->[MISC ERRORS]<-----
|
//* ----->[MISC ERRORS]<-----
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import {
|
|||||||
MEMBER,
|
MEMBER,
|
||||||
INVITED,
|
INVITED,
|
||||||
ACCEPTED,
|
ACCEPTED,
|
||||||
COMPLETED,
|
|
||||||
GRANTED
|
|
||||||
} from './organization';
|
} from './organization';
|
||||||
import { SECRET_SHARED, SECRET_PERSONAL } from './secret';
|
import { SECRET_SHARED, SECRET_PERSONAL } from './secret';
|
||||||
import { EVENT_PUSH_SECRETS, EVENT_PULL_SECRETS } from './event';
|
import { EVENT_PUSH_SECRETS, EVENT_PULL_SECRETS } from './event';
|
||||||
@@ -48,8 +46,6 @@ export {
|
|||||||
MEMBER,
|
MEMBER,
|
||||||
INVITED,
|
INVITED,
|
||||||
ACCEPTED,
|
ACCEPTED,
|
||||||
COMPLETED,
|
|
||||||
GRANTED,
|
|
||||||
SECRET_SHARED,
|
SECRET_SHARED,
|
||||||
SECRET_PERSONAL,
|
SECRET_PERSONAL,
|
||||||
ENV_DEV,
|
ENV_DEV,
|
||||||
|
|||||||
@@ -9,16 +9,10 @@ const INVITED = 'invited';
|
|||||||
// -- organization
|
// -- organization
|
||||||
const ACCEPTED = 'accepted';
|
const ACCEPTED = 'accepted';
|
||||||
|
|
||||||
// -- workspace
|
|
||||||
const COMPLETED = 'completed';
|
|
||||||
const GRANTED = 'granted';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
OWNER,
|
OWNER,
|
||||||
ADMIN,
|
ADMIN,
|
||||||
MEMBER,
|
MEMBER,
|
||||||
INVITED,
|
INVITED,
|
||||||
ACCEPTED,
|
ACCEPTED
|
||||||
COMPLETED,
|
|
||||||
GRANTED
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user