Skip to content

PR for Issue#332 [BE: API key & code snippet] #347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 70 commits into from
Closed
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
711a43f
added `apiKey` and `serverUrl` cols to `teams` rel and gen migration
d02ev Nov 15, 2024
7a18427
added backend API and business logic for `serverUrl` and `apiKey`
d02ev Nov 15, 2024
3fcbb84
fixed controller name typo
d02ev Nov 15, 2024
84c34e9
removed `apiKey` hashing before storing
d02ev Nov 15, 2024
a29edc0
added FE connection to BE
d02ev Nov 15, 2024
94e2e21
coderabbit refactors
d02ev Nov 15, 2024
83020d5
added encryption to `apiKey`
d02ev Nov 16, 2024
92a7566
coderabbit refactors
d02ev Nov 16, 2024
bff615b
feat: Adding a utility function to make settings rbac
aryanp-86 Nov 11, 2024
29f675f
Refactored the utility function
aryanp-86 Nov 13, 2024
f5307c7
Refactored teamtab and settings to ensure consistency
aryanp-86 Nov 14, 2024
5bd78ad
Added reducer functionality for tab change
aryanp-86 Nov 15, 2024
178ed3e
Removed tabValue from authProvider
aryanp-86 Nov 15, 2024
ca02815
refactored teams page
erenfn Nov 15, 2024
8fe21ae
coderabbit
erenfn Nov 15, 2024
f9e05e7
team tab refactor
erenfn Nov 15, 2024
74b5bca
Draft1 - Refactor data validations for controllers in backend
eulerbutcooler Oct 16, 2024
2c279da
auth validation - backend + frontend
eulerbutcooler Oct 29, 2024
b375c61
Auth validations - frontend and backend
eulerbutcooler Nov 12, 2024
a7f3dea
undid some comments
eulerbutcooler Nov 12, 2024
9456dd5
Fixed onBlur validation checks
eulerbutcooler Nov 13, 2024
f73bb8d
Enhanced login page with sign-up link, improved validation for name a…
eulerbutcooler Nov 14, 2024
a1e30b1
Added suggested edits
eulerbutcooler Nov 14, 2024
97cc6a3
undid a comment
eulerbutcooler Nov 14, 2024
f1802ea
more edits
eulerbutcooler Nov 14, 2024
234d093
updated the auth tests and made minor changes to name regex
eulerbutcooler Nov 16, 2024
2b210b2
admin register routes
erenfn Nov 16, 2024
1fc68e6
Update docker-compose.yml
erenfn Nov 16, 2024
1dd7964
Merge branch 'develop' into d02ev/issue#332
d02ev Nov 29, 2024
afde799
update error toast and added config fetch
d02ev Nov 29, 2024
19553c1
BE refactors
d02ev Dec 3, 2024
3ebaf7f
Merge branch 'develop' into d02ev/issue#332
d02ev Dec 7, 2024
eeb97c3
resolved merge conflict
d02ev Dec 7, 2024
55c9865
comment resolution
d02ev Dec 7, 2024
6247039
Merge branch 'develop' into d02ev/issue#332
d02ev Dec 14, 2024
df26b0c
updated setConfig validations
d02ev Dec 14, 2024
3298934
feat: add column action url to models
DeboraSerra Dec 10, 2024
af26153
feat: add migrations
DeboraSerra Dec 10, 2024
23081e3
feat: add validation on controller to actionUrl column
DeboraSerra Dec 10, 2024
bf2b3b0
feat: add action url to banner in front
DeboraSerra Dec 13, 2024
a14f07a
feat: add action url to popup front
DeboraSerra Dec 13, 2024
1e87754
chore: add proptypes to banner and popup content
DeboraSerra Dec 14, 2024
75db228
chore: improve url validation on model
DeboraSerra Dec 14, 2024
09e76c9
chore: improve url validation on front
DeboraSerra Dec 14, 2024
7ce60ba
chore: improve url validation on controller
DeboraSerra Dec 14, 2024
5d11055
fix: fix error return on popup
DeboraSerra Dec 14, 2024
47defaa
chore: remove console log from popup front
DeboraSerra Dec 14, 2024
9a9c734
test: fix test on front
DeboraSerra Dec 14, 2024
ceec1e9
test: fix test on back
DeboraSerra Dec 14, 2024
2ce3cad
fix: fix error return on banner
DeboraSerra Dec 14, 2024
5b3aef0
feat: add column action url to models
DeboraSerra Dec 10, 2024
23d97d0
feat: add validation on controller to actionUrl column
DeboraSerra Dec 10, 2024
db9c7d1
feat: add action url to banner in front
DeboraSerra Dec 13, 2024
3cd8584
feat: add action url to popup front
DeboraSerra Dec 13, 2024
777cce7
chore: add proptypes to banner and popup content
DeboraSerra Dec 14, 2024
32aa954
chore: improve url validation on model
DeboraSerra Dec 14, 2024
f9e5748
chore: improve url validation on front
DeboraSerra Dec 14, 2024
9ef45c4
chore: improve url validation on controller
DeboraSerra Dec 14, 2024
b47b6f5
fix: fix error return on popup
DeboraSerra Dec 14, 2024
2018c5d
chore: remove console log from popup front
DeboraSerra Dec 14, 2024
43fbb22
test: fix test on back
DeboraSerra Dec 14, 2024
161bf4c
fix: fix error return on banner
DeboraSerra Dec 14, 2024
2bf8716
guide init
erenfn Dec 10, 2024
6039fe4
resolve dockerfile
erenfn Dec 10, 2024
2bdf41f
find incomplete guides done
erenfn Dec 11, 2024
b368d09
Update guide.routes.js
erenfn Dec 11, 2024
dd16c3c
added getPopupByApiAndClientId
erenfn Dec 11, 2024
b57420c
Merge branch 'develop' into d02ev/issue#332
d02ev Dec 16, 2024
2be6c41
resolved merge issues
d02ev Dec 16, 2024
3e945a6
updated server url and api key allowed values
d02ev Dec 16, 2024
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
3 changes: 3 additions & 0 deletions backend/.env
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ EMAIL_ENABLE=false
# JWT Secret Key
JWT_SECRET="NKrbO2lpCsOpVAlqAPsjZ0tZXzIoKru7gAmYZ7XlHn0=qqwqeq"

# API KEY ENCRYPTION SECRET KEY
API_KEY_ENCRYPTION_KEY="\wd?jqf7o5*v;[{/s$9_u3`h+i4r2(^ymt'#|kn-@~!x1ea6pb"

TEST_DB_USERNAME=user123
TEST_DB_PASSWORD=password123
TEST_DB_NAME=onboarding_db_test
Expand Down
3 changes: 3 additions & 0 deletions backend/.env.production
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ PROD_DB_PORT=5432

# JWT Secret Key
JWT_SECRET=your_prod_jwt_secret_key_here

# API KEY ENCRYPTION SECRET KEY
API_KEY_ENCRYPTION_KEY=your_prod_api_key_encryption_key_here
3 changes: 3 additions & 0 deletions backend/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ POSTGRES_DB=onboarding_db_test

# JWT Secret Key
JWT_SECRET=your_test_jwt_secret_key_here

# API KEY ENCRYPTION SECRET KEY
API_KEY_ENCRYPTION_KEY=your_prod_api_key_encryption_key_here
1 change: 1 addition & 0 deletions backend/config/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
popups: [userRole.ADMIN],
hints: [userRole.ADMIN],
banners: [userRole.ADMIN],
serverUrlAndApiKey: [userRole.ADMIN],
links: [userRole.ADMIN],
tours: [userRole.ADMIN],
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

module.exports = {
async up (queryInterface, Sequelize) {
await queryInterface.addColumn('teams', 'apiKey', {
type: Sequelize.TEXT,
allowNull: true,
defaultValue: null,
})
await queryInterface.addColumn('teams', 'serverUrl', {
type: Sequelize.TEXT,
allowNull: true,
defaultValue: null,
})
},

async down (queryInterface, Sequelize) {
await queryInterface.removeColumn('teams', 'apiKey')
await queryInterface.removeColumn('teams', 'serverUrl')
}
};
18 changes: 18 additions & 0 deletions backend/migrations/20241210225728-add-action-url-banner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"use strict";

/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addColumn("banners", "actionUrl", {
type: Sequelize.STRING,
allowNull: true,
validate: {
isUrl: true,
},
});
},

async down(queryInterface, Sequelize) {
await queryInterface.removeColumn("banners", "actionUrl");
},
};
18 changes: 18 additions & 0 deletions backend/migrations/20241210225734-add-action-url-popup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"use strict";

/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addColumn("popup", "actionUrl", {
type: Sequelize.STRING,
allowNull: true,
validate: {
isUrl: true,
},
});
},

async down(queryInterface, Sequelize) {
await queryInterface.removeColumn("popup", "actionUrl");
},
};
134 changes: 93 additions & 41 deletions backend/src/controllers/banner.controller.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,61 @@
const bannerService = require("../service/banner.service.js");
const { internalServerError } = require("../utils/errors.helper");
const { validateCloseButtonAction } = require("../utils/guide.helper");
const { validatePosition } = require("../utils/banner.helper");
const {
validatePosition,
validateUrl,
validateRelativeUrl,
} = require("../utils/banner.helper");
const { checkColorFieldsFail } = require("../utils/guide.helper");

class BannerController {
async addBanner(req, res) {
const userId = req.user.id;
const { position, closeButtonAction, fontColor, backgroundColor } = req.body;
const {
position,
closeButtonAction,
fontColor,
backgroundColor,
actionUrl,
url,
} = req.body;

if (!position || !closeButtonAction) {
return res
.status(400)
.json({
errors: [{ msg: "position and closeButtonAction are required" }],
});
return res.status(400).json({
errors: [{ msg: "position and closeButtonAction are required" }],
});
}

if (!validatePosition(position) || !validateCloseButtonAction(closeButtonAction)) {
return res
.status(400)
.json({
errors: [{ msg: "Invalid value entered" }],
});
if (
!validatePosition(position) ||
!validateCloseButtonAction(closeButtonAction)
) {
return res.status(400).json({
errors: [{ msg: "Invalid value entered" }],
});
}

if (actionUrl) {
try {
validateUrl(actionUrl, "actionUrl");
} catch (err) {
return res.status(400).json({ errors: [{ msg: err.message }] });
}
}

if (url) {
try {
validateRelativeUrl(url, "url");
} catch (err) {
return res.status(400).json({ errors: [{ msg: err.message }] });
}
}

const colorFields = { fontColor, backgroundColor };
const colorCheck = checkColorFieldsFail(colorFields, res)
if (colorCheck) { return colorCheck };
const colorCheck = checkColorFieldsFail(colorFields, res);
if (colorCheck) {
return colorCheck;
}

try {
const newBannerData = { ...req.body, createdBy: userId };
Expand All @@ -37,7 +65,7 @@ class BannerController {
console.log(err);
const { statusCode, payload } = internalServerError(
"CREATE_BANNER_ERROR",
err.message,
err.message
);
res.status(statusCode).json(payload);
}
Expand All @@ -54,11 +82,9 @@ class BannerController {
const deletionResult = await bannerService.deleteBanner(id);

if (!deletionResult) {
return res
.status(400)
.json({
errors: [{ msg: "Banner with the specified id does not exist" }],
});
return res.status(400).json({
errors: [{ msg: "Banner with the specified id does not exist" }],
});
}

res
Expand All @@ -67,7 +93,7 @@ class BannerController {
} catch (err) {
const { statusCode, payload } = internalServerError(
"DELETE_BANNER_ERROR",
err.message,
err.message
);
res.status(statusCode).json(payload);
}
Expand All @@ -76,14 +102,19 @@ class BannerController {
async editBanner(req, res) {
try {
const { id } = req.params;
const { fontColor, backgroundColor, url, position, closeButtonAction, bannerText } = req.body;
const {
fontColor,
backgroundColor,
url,
position,
closeButtonAction,
actionUrl,
} = req.body;

if (!position || !closeButtonAction) {
return res
.status(400)
.json({
errors: [{ msg: "position and closeButtonAction are required" }],
});
return res.status(400).json({
errors: [{ msg: "position and closeButtonAction are required" }],
});
}

if (!validatePosition(position)) {
Expand All @@ -98,16 +129,34 @@ class BannerController {
.json({ errors: [{ msg: "Invalid value for closeButtonAction" }] });
}

if (actionUrl) {
try {
validateUrl(actionUrl, "actionUrl");
} catch (err) {
return res.status(400).json({ errors: [{ msg: err.message }] });
}
}

if (url) {
try {
validateRelativeUrl(url, "url");
} catch (err) {
return res.status(400).json({ errors: [{ msg: err.message }] });
}
}

const colorFields = { fontColor, backgroundColor };
const colorCheck = checkColorFieldsFail(colorFields, res)
if (colorCheck) { return colorCheck };
const colorCheck = checkColorFieldsFail(colorFields, res);
if (colorCheck) {
return colorCheck;
}

const updatedBanner = await bannerService.updateBanner(id, req.body);
res.status(200).json(updatedBanner);
} catch (err) {
const { statusCode, payload } = internalServerError(
"EDIT_BANNER_ERROR",
err.message,
err.message
);
res.status(statusCode).json(payload);
}
Expand All @@ -120,7 +169,7 @@ class BannerController {
} catch (err) {
const { statusCode, payload } = internalServerError(
"GET_ALL_BANNERS_ERROR",
err.message,
err.message
);
res.status(statusCode).json(payload);
}
Expand All @@ -133,8 +182,8 @@ class BannerController {
res.status(200).json(banners);
} catch (err) {
const { statusCode, payload } = internalServerError(
"GET\_BANNERS_ERROR",
err.message,
"GET_BANNERS_ERROR",
err.message
);
res.status(statusCode).json(payload);
}
Expand All @@ -158,7 +207,7 @@ class BannerController {
} catch (err) {
const { statusCode, payload } = internalServerError(
"GET_BANNER_BY_ID_ERROR",
err.message,
err.message
);
res.status(statusCode).json(payload);
}
Expand All @@ -167,19 +216,22 @@ class BannerController {
try {
const { url } = req.body;

if (!url || typeof url !== 'string' ) {
return res.status(400).json({ errors: [{ msg: "URL is missing or invalid" }] });
if (!url || typeof url !== "string") {
return res
.status(400)
.json({ errors: [{ msg: "URL is missing or invalid" }] });
}

const banner = await bannerService.getBannerByUrl(url);
res.status(200).json({banner});
res.status(200).json({ banner });
} catch (error) {
internalServerError(
const { payload, statusCode } = internalServerError(
"GET_BANNER_BY_URL_ERROR",
error.message,
error.message
);
res.status(statusCode).json(payload);
}
};
}
}

module.exports = new BannerController();
Loading
Loading