Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/app/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ module.exports = {
'src/server/routes/apiv3/security-settings/**',
'src/server/routes/apiv3/app-settings/**',
'src/server/routes/apiv3/page/**',
'src/server/routes/apiv3/*.ts',
],
settings: {
// resolve path aliases by eslint-import-resolver-typescript
Expand Down
87 changes: 50 additions & 37 deletions apps/app/src/server/routes/apiv3/activity.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
import { SCOPE } from '@growi/core/dist/interfaces';
import { serializeUserSecurely } from '@growi/core/dist/models/serializers';
import { parseISO, addMinutes, isValid } from 'date-fns';
import { addMinutes, isValid, parseISO } from 'date-fns';
import type { Request, Router } from 'express';
import express from 'express';
import { query } from 'express-validator';

import type { IActivity, ISearchFilter } from '~/interfaces/activity';
import { SCOPE } from '@growi/core/dist/interfaces';
import { accessTokenParser } from '~/server/middlewares/access-token-parser';
import Activity from '~/server/models/activity';
import { configManager } from '~/server/service/config-manager';
import loggerFactory from '~/utils/logger';

import type Crowi from '../../crowi';
import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';

import type { ApiV3Response } from './interfaces/apiv3-response';


const logger = loggerFactory('growi:routes:apiv3:activity');


const validator = {
list: [
query('limit').optional().isInt({ max: 100 }).withMessage('limit must be a number less than or equal to 100'),
query('limit')
.optional()
.isInt({ max: 100 })
.withMessage('limit must be a number less than or equal to 100'),
query('offset').optional().isInt().withMessage('page must be a number'),
query('searchFilter').optional().isString().withMessage('query must be a string'),
query('searchFilter')
.optional()
.isString()
.withMessage('query must be a string'),
],
};

Expand Down Expand Up @@ -171,7 +174,9 @@ const validator = {

module.exports = (crowi: Crowi): Router => {
const adminRequired = require('../../middlewares/admin-required')(crowi);
const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
const loginRequiredStrictly = require('../../middlewares/login-required')(
crowi,
);

const router = express.Router();

Expand Down Expand Up @@ -209,38 +214,51 @@ module.exports = (crowi: Crowi): Router => {
* schema:
* $ref: '#/components/schemas/ActivityResponse'
*/
router.get('/',
router.get(
'/',
accessTokenParser([SCOPE.READ.ADMIN.AUDIT_LOG], { acceptLegacy: true }),
loginRequiredStrictly, adminRequired, validator.list, apiV3FormValidator, async(req: Request, res: ApiV3Response) => {
loginRequiredStrictly,
adminRequired,
validator.list,
apiV3FormValidator,
async (req: Request, res: ApiV3Response) => {
const auditLogEnabled = configManager.getConfig('app:auditLogEnabled');
if (!auditLogEnabled) {
const msg = 'AuditLog is not enabled';
logger.error(msg);
return res.apiv3Err(msg, 405);
}

const limit = req.query.limit || configManager.getConfig('customize:showPageLimitationS');
const limit =
req.query.limit ||
configManager.getConfig('customize:showPageLimitationS');
const offset = req.query.offset || 1;

const query = {};

try {
const parsedSearchFilter = JSON.parse(req.query.searchFilter as string) as ISearchFilter;
const parsedSearchFilter = JSON.parse(
req.query.searchFilter as string,
) as ISearchFilter;

// add username to query
const canContainUsernameFilterToQuery = (
parsedSearchFilter.usernames != null
&& parsedSearchFilter.usernames.length > 0
&& parsedSearchFilter.usernames.every(u => typeof u === 'string')
);
const canContainUsernameFilterToQuery =
parsedSearchFilter.usernames != null &&
parsedSearchFilter.usernames.length > 0 &&
parsedSearchFilter.usernames.every((u) => typeof u === 'string');
if (canContainUsernameFilterToQuery) {
Object.assign(query, { 'snapshot.username': parsedSearchFilter.usernames });
Object.assign(query, {
'snapshot.username': parsedSearchFilter.usernames,
});
}

// add action to query
if (parsedSearchFilter.actions != null) {
const availableActions = crowi.activityService.getAvailableActions(false);
const searchableActions = parsedSearchFilter.actions.filter(action => availableActions.includes(action));
const availableActions =
crowi.activityService.getAvailableActions(false);
const searchableActions = parsedSearchFilter.actions.filter(
(action) => availableActions.includes(action),
);
Object.assign(query, { action: searchableActions });
}

Expand All @@ -255,8 +273,7 @@ module.exports = (crowi: Crowi): Router => {
$lt: addMinutes(endDate, 1439),
},
});
}
else if (isValid(startDate) && !isValid(endDate)) {
} else if (isValid(startDate) && !isValid(endDate)) {
Object.assign(query, {
createdAt: {
$gte: startDate,
Expand All @@ -265,23 +282,19 @@ module.exports = (crowi: Crowi): Router => {
},
});
}
}
catch (err) {
} catch (err) {
logger.error('Invalid value', err);
return res.apiv3Err(err, 400);
}

try {
const paginateResult = await Activity.paginate(
query,
{
lean: true,
limit,
offset,
sort: { createdAt: -1 },
populate: 'user',
},
);
const paginateResult = await Activity.paginate(query, {
lean: true,
limit,
offset,
sort: { createdAt: -1 },
populate: 'user',
});

const serializedDocs = paginateResult.docs.map((doc: IActivity) => {
const { user, ...rest } = doc;
Expand All @@ -297,12 +310,12 @@ module.exports = (crowi: Crowi): Router => {
};

return res.apiv3({ serializedPaginationResult });
}
catch (err) {
} catch (err) {
logger.error('Failed to get paginated activity', err);
return res.apiv3Err(err, 500);
}
});
},
);

return router;
};
41 changes: 26 additions & 15 deletions apps/app/src/server/routes/apiv3/admin-home.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { SCOPE } from '@growi/core/dist/interfaces';

import { accessTokenParser } from '~/server/middlewares/access-token-parser';
import { configManager } from '~/server/service/config-manager';
import { getGrowiVersion } from '~/utils/growi-version';
Expand Down Expand Up @@ -60,7 +61,9 @@ const router = express.Router();
*/
/** @param {import('~/server/crowi').default} crowi Crowi instance */
module.exports = (crowi) => {
const loginRequiredStrictly = require('../../middlewares/login-required')(crowi);
const loginRequiredStrictly = require('../../middlewares/login-required')(
crowi,
);
const adminRequired = require('../../middlewares/admin-required')(crowi);

/**
Expand All @@ -83,22 +86,30 @@ module.exports = (crowi) => {
* adminHomeParams:
* $ref: "#/components/schemas/SystemInformationParams"
*/
router.get('/', accessTokenParser([SCOPE.READ.ADMIN.TOP]), loginRequiredStrictly, adminRequired, async(req, res) => {
const { getRuntimeVersions } = await import('~/server/util/runtime-versions');
const runtimeVersions = await getRuntimeVersions();
router.get(
'/',
accessTokenParser([SCOPE.READ.ADMIN.TOP]),
loginRequiredStrictly,
adminRequired,
async (req, res) => {
const { getRuntimeVersions } = await import(
'~/server/util/runtime-versions'
);
const runtimeVersions = await getRuntimeVersions();

const adminHomeParams = {
growiVersion: getGrowiVersion(),
nodeVersion: runtimeVersions.node ?? '-',
npmVersion: runtimeVersions.npm ?? '-',
pnpmVersion: runtimeVersions.pnpm ?? '-',
envVars: configManager.getManagedEnvVars(),
isV5Compatible: configManager.getConfig('app:isV5Compatible'),
isMaintenanceMode: configManager.getConfig('app:isMaintenanceMode'),
};
const adminHomeParams = {
growiVersion: getGrowiVersion(),
nodeVersion: runtimeVersions.node ?? '-',
npmVersion: runtimeVersions.npm ?? '-',
pnpmVersion: runtimeVersions.pnpm ?? '-',
envVars: configManager.getManagedEnvVars(),
isV5Compatible: configManager.getConfig('app:isV5Compatible'),
isMaintenanceMode: configManager.getConfig('app:isMaintenanceMode'),
};

return res.apiv3({ adminHomeParams });
});
return res.apiv3({ adminHomeParams });
},
);

return router;
};
Loading
Loading