Skip to content

Commit

Permalink
Merge pull request #366 from ONSdigital/BLAIS5-3816
Browse files Browse the repository at this point in the history
Promote from BLAIS5-3816 to main
  • Loading branch information
motalm authored Jul 5, 2024
2 parents e2cfee2 + 7687e82 commit 133f65f
Show file tree
Hide file tree
Showing 58 changed files with 3,240 additions and 629 deletions.
195 changes: 82 additions & 113 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,119 +1,88 @@
{
"ignorePatterns": [
"node_modules/*",
"dist/*",
"build/*"
],
"env": {
"browser": true,
"es2021": true,
"node": true
"ignorePatterns": ["node_modules/*", "dist/*", "build/*"],
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint", "import"],
"rules": {
"object-curly-spacing": ["error", "always"],
"no-multiple-empty-lines": [
"error",
{
"max": 1
}
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react",
"@typescript-eslint",
"import"
"no-trailing-spaces": "error",
"no-mixed-spaces-and-tabs": "error",
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
"no-undef": "off",
"comma-dangle": ["error", "never"],
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-unused-vars": "off",
"react/react-in-jsx-scope": "off",
"react/require-default-props": "off",
"no-spaced-func": "off",
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
],
"rules": {
"object-curly-spacing": ["error", "always"],
"no-multiple-empty-lines": [
"error",
{
"max": 1
}
],
"no-trailing-spaces": "error",
"no-mixed-spaces-and-tabs": "error",
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"no-undef": "off",
"comma-dangle": [
"error",
"never"
],
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-unused-vars": "off",
"react/react-in-jsx-scope": "off",
"react/require-default-props": "off",
"no-spaced-func": "off",
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
],
"max-len": [
"error",
{
"code": 200
}
],
"@typescript-eslint/no-empty-function": "off",
"indent": [
"error",
4
],
"space-in-parens": [
"error",
"never"
],
"no-multi-spaces": "error",
"comma-spacing": [
"error",
{
"before": false,
"after": true
}
],
"template-curly-spacing": [
"error",
"never"
]
},
"overrides": [
{
"files": [
"*.js"
],
"rules": {
"@typescript-eslint/no-var-requires": "off"
}
}
"max-len": [
"error",
{
"code": 200
}
],
"settings": {
"react": {
"createClass": "createReactClass", // Regex for Component Factory to use,
// default to "createReactClass"
"pragma": "React", // Pragma to use, default to "React"
"fragment": "Fragment", // Fragment to use (may be a property of <pragma>), default to "Fragment"
"version": "detect", // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
// It will default to "detect" in the future
"flowVersion": "0.53" // Flow version
}
"@typescript-eslint/no-empty-function": "off",
"indent": ["error", 4],
"space-in-parens": ["error", "never"],
"no-multi-spaces": "error",
"comma-spacing": [
"error",
{
"before": false,
"after": true
}
],
"template-curly-spacing": ["error", "never"]
},
"overrides": [
{
"files": ["*.js"],
"rules": {
"@typescript-eslint/no-var-requires": "off"
}
}
],
"settings": {
"react": {
"createClass": "createReactClass", // Regex for Component Factory to use,
// default to "createReactClass"
"pragma": "React", // Pragma to use, default to "React"
"fragment": "Fragment", // Fragment to use (may be a property of <pragma>), default to "Fragment"
"version": "detect", // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
// It will default to "detect" in the future
"flowVersion": "0.53" // Flow version
}
}
}
}
26 changes: 26 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Jest: Run all",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": ["--runInBand"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
},
{
"type": "node",
"request": "launch",
"name": "Jest: Run Current Test File",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": ["--runInBand", "${relativeFile}"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
3 changes: 2 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
process.env = Object.assign(process.env, {
BLAISE_API_URL: "http://mock",
PROJECT_ID: "mock-project",
SERVER_PARK: "mock-server-park"
SERVER_PARK: "mock-server-park",
MOCK_AUTH_TOKEN: "mock-token"
});

module.exports = {
Expand Down
17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"start-server": "tsc --project tsconfig.server.json && node ./dist/index.js | pino-pretty -c -t",
"start-react": "react-scripts start",
"build-react": "react-scripts --openssl-legacy-provider build",
"test": "yarn build-react && tsc --project tsconfig.server.json && jest --coverage --watchAll=false",
"rebuild-test": "yarn build-react && tsc --project tsconfig.server.json && jest --coverage --watchAll=false",
"test": "jest --coverage --watchAll=false",
"gcp-build": "yarn build-react && tsc --project tsconfig.server.json",
"lint-fix": "node_modules/.bin/eslint . --fix",
"lint": "yarn eslint .",
Expand All @@ -30,13 +31,8 @@
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^14.2.1",
"@testing-library/user-event": "^13.5.0",
"@types/express": "^4.17.8",
"@types/jest": "26.0.20",
"@types/node": "^15.12.2",
"@types/react": "^18.2.51",
"@types/react-dom": "^18.2.18",
"axios": "^1.6.1",
"blaise-api-node-client": "https://github.com/ONSdigital/blaise-api-node-client#v1.1.0",
"blaise-api-node-client": "git+https://github.com/ONSdigital/blaise-api-node-client",
"blaise-design-system-react-components": "git+https://github.com/ONSdigital/blaise-design-system-react-components#0.14.0",
"blaise-login-react": "git+https://github.com/ONSdigital/blaise-login-react#1.1.0",
"dotenv": "^10.0.0",
Expand Down Expand Up @@ -65,11 +61,16 @@
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.14.5",
"@types/ejs": "^3.0.5",
"@types/express": "^4.17.8",
"@types/jest": "26.0.20",
"@types/lodash": "^4.14.168",
"@types/multer": "^1.4.5",
"@types/node": "^15.12.2",
"@types/number-to-words": "^1.2.0",
"@types/pino-http": "^5.4.0",
"@types/pino-pretty": "^4.7.1",
"@types/react": "^18.2.51",
"@types/react-dom": "^18.2.18",
"@types/react-router-dom": "^5.3.3",
"@types/supertest": "^6.0.2",
"@typescript-eslint/eslint-plugin": "^6.20.0",
Expand All @@ -78,6 +79,8 @@
"concurrently": "^7.0.0",
"cross-env": "^7.0.2",
"eslint": "^8.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"pino-pretty": "^4.7.1",
Expand Down
62 changes: 60 additions & 2 deletions server/BlaiseAPI/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import BlaiseApiClient from "blaise-api-node-client";

export default function BlaiseAPIRouter(config: CustomConfig, auth: Auth, blaiseApiClient: BlaiseApiClient): Router {
const router = express.Router();

router.get("/api/roles", auth.Middleware, async function (req: Request, res: Response) {
res.status(200).json(await blaiseApiClient.getUserRoles());
});
Expand All @@ -14,7 +13,66 @@ export default function BlaiseAPIRouter(config: CustomConfig, auth: Auth, blaise
res.status(200).json(await blaiseApiClient.getUsers());
});

router.get("/api/change_password/:user", auth.Middleware, async function (req: Request, res: Response) {
router.patch("/api/users/:user/rolesAndPermissions", auth.Middleware, async function (req: Request, res: Response) {
const { role } = req.body;
const user = req.params.user;
let newServerParks = [""];
let newDefaultServerPark = "";

if (!req.params.user || !req.body.role) {
return res.status(400).json("No user or role provided");
}

const roleServerParksOverride = config.RoleToServerParksMap[role];
if (roleServerParksOverride != null) {
newServerParks = roleServerParksOverride;
newDefaultServerPark = roleServerParksOverride[0];
} else {
const defaultServerPark = config.RoleToServerParksMap["DEFAULT"];
newServerParks = defaultServerPark;
newDefaultServerPark = defaultServerPark[0];
}

try {
await blaiseApiClient.changeUserRole(user, role);
await blaiseApiClient.changeUserServerParks(user, newServerParks, newDefaultServerPark);
const successMessage = `Successfully updated user role and permissions to ${role} for ${user}`;
console.log(successMessage + ` at ${(new Date()).toLocaleTimeString("en-UK")} ${(new Date()).toLocaleDateString("en-UK")}`);
return res.status(200).json({
message: successMessage + " today at " + (new Date()).toLocaleTimeString("en-UK")
});
} catch (error) {
const errorMessage = `Error whilst trying to update user role and permissions to ${role} for ${req.params.user}: ${error}`;
console.error(errorMessage);
return res.status(500).json({
message: errorMessage
});
}
});

router.get("/api/users/:user", auth.Middleware, async function (req: Request, res: Response) {
if (!req.params.user) {
return res.status(400).json("No user provided");
}

try {
const user = await blaiseApiClient.getUser(req.params.user);
const successMessage = `Successfully fetched user details for ${req.params.user}`;
return res.status(200).json({
message: successMessage,
data: user
});
} catch (error) {
const errorMessage = `Error whilst trying to retrieve user ${req.params.user}: ${error}`;
console.error(errorMessage);
return res.status(500).json({
message: errorMessage,
error: error
});
}
});

router.get("/api/change-password/:user", auth.Middleware, async function (req: Request, res: Response) {
let { password } = req.headers;

if (Array.isArray(password)) {
Expand Down
1 change: 0 additions & 1 deletion server/interfaces/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AuthConfig } from "blaise-login-react/blaise-login-react-server";
import { string } from "prop-types";

export interface CustomConfig extends AuthConfig {
BlaiseApiUrl: string
Expand Down
9 changes: 7 additions & 2 deletions server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,17 @@ export default function GetNodeServer(config: CustomConfig, blaiseApi: BlaiseApi
if (!fs.existsSync(indexFilePath)) {
indexFilePath = path.join(__dirname, "../public/index.html");
}

server.get("*", function (_req: Request, res: Response) {
res.render(indexFilePath);
});

server.use(function (err: Error, _req: Request, res: Response) {
console.error(err.stack);
server.use(function (err, _req, res, _next) {
if (err && err.stack) {
console.error(err.stack);
} else {
console.error("An undefined error occurred");
}
res.render("../views/500.html", {});
});

Expand Down
Loading

0 comments on commit 133f65f

Please sign in to comment.