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 .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ workflows:
- develop
- pm-2539
- PS-511
- PS-513-Hotfix

# Production builds are exectuted only on tagged commits to the
# master branch.
Expand Down
1 change: 1 addition & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ The following parameters can be set in config files or in env variables:
- PORT: the server port, default is 3000
- AUTH_SECRET: The authorization secret used during token verification.
- VALID_ISSUERS: The valid issuer of tokens.
- VANILLA_DB_URL: MySQL connection string for the Vanilla forums database.
- AUTH0_URL: AUTH0 URL, used to get M2M token
- AUTH0_PROXY_SERVER_URL: AUTH0 proxy server URL, used to get M2M token
- AUTH0_AUDIENCE: AUTH0 audience, used to get M2M token
Expand Down
1 change: 1 addition & 0 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
AUTH_SECRET: process.env.AUTH_SECRET || 'mysecret',
VALID_ISSUERS: process.env.VALID_ISSUERS || '["https://api.topcoder-dev.com", "https://api.topcoder.com", "https://topcoder-dev.auth0.com/", "https://auth.topcoder-dev.com/"]',
IDENTITY_DB_URL: process.env.IDENTITY_DB_URL,
VANILLA_DB_URL: process.env.VANILLA_DB_URL,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ security]
Ensure that VANILLA_DB_URL is properly validated and sanitized before use to prevent potential security vulnerabilities such as SQL injection.


// used to get M2M token
AUTH0_URL: process.env.AUTH0_URL,
Expand Down
3 changes: 2 additions & 1 deletion config/test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ paths:
description: |-
Update the member profile by handle.

Handle updates are not supported on this endpoint. Use `PATCH /members/{handle}/change_handle` to change handles.

If the email has been changed, the email change process starts and a verification email is sent to the new and old email address.

Authorization:
Expand Down Expand Up @@ -332,6 +334,59 @@ paths:
description: Internal server error
schema:
$ref: '#/definitions/ErrorModel'
'/members/{handle}/change_handle':
patch:
tags:
- Basic
description: |-
Update the member handle.

Authorization:
- JWT roles: Only the profile owner or users with `administrator`/`admin` roles may update member data.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ security]
The authorization description mentions administrator and admin roles separately. Ensure that these roles are distinct and correctly implemented in the authorization logic, as redundancy or misconfiguration could lead to security issues.

- M2M scopes: `update:user_profiles` or `all:user_profiles`.
security:
- bearer: []
parameters:
- in: path
name: handle
required: true
type: string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Consider specifying a pattern or length constraint for the handle parameter to prevent potential issues with unexpected input formats.

- in: query
name: fields
required: false
type: string
description: >
Comma separated list of fields to include in the response. Defaults to all member fields.
- in: body
name: body
required: true
schema:
$ref: '#/definitions/MemberHandleUpdate'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The MemberHandleUpdate schema should include validation constraints for newHandle, such as length and allowed characters, to ensure data integrity and prevent potential issues with invalid handle formats.

responses:
'200':
description: OK
schema:
$ref: '#/definitions/MemberProfile'
'400':
description: Bad request data
schema:
$ref: '#/definitions/ErrorModel'
'401':
description: Miss or wrong authentication credentials
schema:
$ref: '#/definitions/ErrorModel'
'403':
description: No permission
schema:
$ref: '#/definitions/ErrorModel'
'404':
description: Not found
schema:
$ref: '#/definitions/ErrorModel'
'500':
description: Internal server error
schema:
$ref: '#/definitions/ErrorModel'
'/members/{handle}/profileCompleteness':
get:
tags:
Expand Down Expand Up @@ -1793,6 +1848,14 @@ definitions:
description: 'ISO-8601 formatted date times (YYYY-MM-DDTHH:mm:ss.sssZ)'
updatedBy:
type: string
MemberHandleUpdate:
type: object
required:
- newHandle
properties:
newHandle:
type: string
description: New handle for the member.
EmailVerificationResult:
type: object
properties:
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"lodash": "^4.17.19",
"mime-types": "^2.1.35",
"moment": "^2.27.0",
"mysql2": "^3.14.3",
"prisma": "^6.10.1",
"request": "^2.88.2",
"sharp": "^0.34.1",
Expand Down
82 changes: 82 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions src/common/vanillaDb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const config = require('config')
const mysql = require('mysql2/promise')
const errors = require('./errors')

let vanillaPool

function getVanillaPool () {
if (!config.VANILLA_DB_URL) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Using config.VANILLA_DB_URL directly without validation could lead to runtime errors if the URL is malformed. Consider validating the URL format before creating the pool.

throw new errors.BadRequestError('VANILLA_DB_URL is not configured')
}

if (!vanillaPool) {
vanillaPool = mysql.createPool(config.VANILLA_DB_URL)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ performance]
The createPool method should be configured with additional options such as connection limits, timeouts, etc., to ensure optimal performance and resource management.

}

return vanillaPool
}

module.exports = {
getVanillaPool
}
11 changes: 11 additions & 0 deletions src/controllers/MemberController.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ async function updateMember (req, res) {
res.send(result)
}

/**
* Update member handle
* @param {Object} req the request
* @param {Object} res the response
*/
async function updateHandle (req, res) {
const result = await service.updateHandle(req.authUser, req.params.handle, req.query, req.body)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
Consider adding error handling for the service.updateHandle call to ensure that any exceptions are properly managed and do not result in unhandled promise rejections.

res.send(result)
}

/**
* Verify email
* @param {Object} req the request
Expand Down Expand Up @@ -77,6 +87,7 @@ module.exports = {
getProfileCompleteness,
getMemberUserIdSignature,
updateMember,
updateHandle,
verifyEmail,
uploadPhoto,
deleteMember
Expand Down
9 changes: 9 additions & 0 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ module.exports = {
access: constants.ADMIN_ROLES
}
},
'/members/:handle/change_handle': {
patch: {
controller: 'MemberController',
method: 'updateHandle',
auth: 'jwt',
access: constants.ADMIN_ROLES,
scopes: [MEMBERS.UPDATE, MEMBERS.ALL]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ security]
The access property is set to constants.ADMIN_ROLES, which is consistent with other routes requiring admin access. However, ensure that constants.ADMIN_ROLES is correctly defined and includes all necessary roles for this operation.

}
},
'/members/:handle/profileCompleteness': {
get: {
controller: 'MemberController',
Expand Down
Loading
Loading