Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
19 changes: 18 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb"

Choose a reason for hiding this comment

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

Consider removing the hardcoded credentials in the DATABASE_URL for security reasons. It's better to use placeholders like <username> and <password>.

POSTGRES_SCHEMA="public"
# API configs
BUS_API_URL="https://api.topcoder-dev.com/v5/bus/events"
CHALLENGE_API_URL="https://api.topcoder-dev.com/v5/challenges/"
MEMBER_API_URL="https://api.topcoder-dev.com/v5/members"
# M2m configs
M2M_AUTH_URL="https://auth0.topcoder-dev.com/oauth/token"
M2M_AUTH_CLIENT_ID="jGIf2pd3f44B1jqvOai30BIKTZanYBfU"
M2M_AUTH_CLIENT_SECRET="ldzqVaVEbqhwjM5KtZ79sG8djZpAVK8Z7qieVcC3vRjI4NirgcinKSBpPwk6mYYP"
M2M_AUTH_DOMAIN="topcoder-dev.auth0.com"
M2M_AUTH_AUDIENCE="https://m2m.topcoder-dev.com/"

Choose a reason for hiding this comment

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

Typo correction: The variable name M2M_AUTH_PROXY_SEREVR_URL was corrected to M2M_AUTH_PROXY_SERVER_URL. Ensure that this change is reflected in all parts of the codebase where this variable is used.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@billsedison - We shouldn't have any mock client ids, tokens, or secrets in the codebase, even though they aren't valid. We get pinged by Wipro security on those and they don't understand that these aren't usable.

M2M_AUTH_PROXY_SERVER_URL=
# Mock API configs
M2M_MOCK_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiakdJZjJwZDNmNDRCMWpxdk9haTMwQklLVFphbllCZlVAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNzQ4MDk5NDk4LCJleHAiOjE4NDgxODU4OTgsInNjb3BlIjoid3JpdGU6YnVzX2FwaSxhbGw6Y2hhbGxlbmdlcyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyIsImF6cCI6ImpHSWYycGQzZjQ0QjFqcXZPYWkzMEJJS1RaYW5ZQmZVIn0.h3ksdsdJm5USGF1VgROrpkTtStmCzv5ZA6y8bd8AnGY"

Choose a reason for hiding this comment

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

Security concern: The M2M_MOCK_TOKEN contains a JWT token in the sample environment file. Consider whether this token should be included here, as it might expose sensitive information. If it's necessary for testing, ensure it's a non-sensitive mock token.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@billsedison - We shouldn't have any mock client ids, tokens, or secrets in the codebase, even though they aren't valid. We get pinged by Wipro security on those and they don't understand that these aren't usable.

#Sendgrid email templates
SENDGRID_ACCEPT_REVIEW_APPLICATION="d-2de72880bd69499e9c16369398d34bb9"
SENDGRID_REJECT_REVIEW_APPLICATION="d-82ed74e778e84d8c9bc02eeda0f44b5e"
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ $ pnpm run start:prod
# run postgres in docker, or other approach
docker run -p 5432:5432 -e POSTGRES_PASSWORD=mysecretpassword postgres:14

export DATABASE_URL="postgresql://postgres:mysecretpassword@localhost:5432/postgres?schema=public"
# Configure the database connection URL (without schema parameter)
export DATABASE_URL="postgresql://postgres:mysecretpassword@localhost:5432/postgres"

# Configure the PostgreSQL schema (defaults to 'public' if not specified)
export POSTGRES_SCHEMA="public"

# run migration
npx prisma migrate dev
Expand All @@ -48,11 +52,32 @@ npx prisma migrate reset
#- `update_foreign_keys`
```

## Schema Configuration

The application supports configurable PostgreSQL schemas through the `POSTGRES_SCHEMA` environment variable:

```bash
# Set the schema for development
export POSTGRES_SCHEMA="dev_schema"

# Set the schema for production
export POSTGRES_SCHEMA="prod_schema"

# If not specified, the application defaults to the 'public' schema
```

This allows you to:
- Use different schemas for different environments (development, testing, production)
- Isolate data for different instances of the application
- Improve security by separating schemas based on environment

## Data import

- create a .env file `mv .env.sample .env`
- update the postgres database url in .env file —
`DATABASE_URL="postgresql://postgres:mysecretpassword@localhost:5432/postgres?schema=public"`
`DATABASE_URL="postgresql://postgres:mysecretpassword@localhost:5432/postgres"`
- set the PostgreSQL schema in .env file —
`POSTGRES_SCHEMA="public"` (or your preferred schema name)
- place all the legacy json files in the `prisma/Scorecards` directory or specify it in .env file — `DATA_DIR=/path/to/Scorecards/folder/`
- install dependencies `pnpm install`
- run the prisma migration `npx prisma migrate dev`
Expand Down
8 changes: 8 additions & 0 deletions appStartUp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ set -eo pipefail

export DATABASE_URL=$(echo -e ${DATABASE_URL})

Choose a reason for hiding this comment

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

Using echo -e with variable substitution can lead to unexpected behavior if the variable contains escape sequences. Consider using printf for safer handling of variables.


# Set default schema to 'public' if not provided
if [ -z "$POSTGRES_SCHEMA" ]; then
echo "POSTGRES_SCHEMA not set, defaulting to 'public'"
export POSTGRES_SCHEMA="public"
else
echo "Using PostgreSQL schema: $POSTGRES_SCHEMA"
fi

echo "Database - running migrations."
if $RESET_DB; then

Choose a reason for hiding this comment

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

The condition $RESET_DB assumes that RESET_DB is a command or a boolean. Ensure that RESET_DB is properly initialized and is a boolean value to avoid unexpected behavior.

echo "Resetting DB"
Expand Down
86 changes: 86 additions & 0 deletions mock/mock-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const express = require('express')
const winston = require('winston')
const cors = require('cors')

const app = express()
app.use(cors())
app.use(express.json())
app.set('port', 4000)

const logger = winston.createLogger({
transports: [
new winston.transports.Console({
level: 'debug',
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple()
),
}),
]
});

// Event bus
app.post('/eventBus', (req, res) => {
logger.info(`Event Bus received message: ${JSON.stringify(req.body)}`);
res.statusCode = 200;
Copy link

Choose a reason for hiding this comment

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

Instead of setting res.statusCode = 200;, use res.status(200); for consistency and readability.

res.json({})
})

// Use environment variable for M2M token instead of hardcoding
const m2mToken = process.env.M2M_MOCK_TOKEN || 'dummy-token';

Choose a reason for hiding this comment

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

Using a hardcoded fallback token ('dummy-token') can be a security risk if it is accidentally used in production. Consider removing the fallback or ensuring it is only used in a safe development environment.


const m2mScope = 'write:bus_api,all:challenges';

// Auth0
app.post('/oauth/token', (req, res) => {
logger.info('Getting M2M tokens')
res.json({
access_token: m2mToken,
scope: m2mScope,
expires_in: 94608000,
token_type: 'Bearer'
})
})

// Member API
app.get('/members', (req, res) => {
logger.info(`Member API receives params: ${JSON.stringify(req.query)}`)
let userIdStr = req.query.userIds
userIdStr = userIdStr.replaceAll('[', '').replaceAll(']', '')
Copy link

Choose a reason for hiding this comment

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

Using replaceAll might not be supported in all environments. Consider using a more compatible method such as replace with a regular expression.

const userIds = userIdStr.split(',')
// return result
const ret = userIds.map(id => ({
userId: parseInt(id),
email: `${id}@topcoder.com`
}))
res.json(ret)
})

// Challenge API
app.get('/challenges/:id', (req, res) => {
// directly challenge details
const id = req.params.id
logger.info(`Getting challenge with id ${id}`)
if (id === '11111111-2222-3333-9999-444444444444') {
Copy link

Choose a reason for hiding this comment

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

Consider using res.status(404).json({}); for setting the status and sending the response in a single chain for better readability.

res.statusCode = 404
res.json({})
return
}
res.json({
id,
name: `Test Challenge ${id}`,
legacy: {
track: 'DEVELOP',
subTrack: 'CODE'
},
numOfSubmissions: 2,
legacyId: 30376875,
tags: ['Prisma', 'NestJS']
})
})


app.listen(app.get('port'), '0.0.0.0', () => {
logger.info(`Express server listening on port ${app.get('port')}`)
})

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,24 @@
"postinstall": "npx prisma generate"
},
"dependencies": {
"@nestjs/axios": "^4.0.0",
"@nestjs/common": "^11.0.1",
"@nestjs/core": "^11.0.1",
"@nestjs/mapped-types": "^2.1.0",
"@nestjs/platform-express": "^11.0.1",
"@nestjs/swagger": "^11.0.3",
"@prisma/client": "^6.3.1",
"@types/jsonwebtoken": "^9.0.9",
"axios": "^1.9.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cors": "^2.8.5",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.2.0",
"nanoid": "~5.1.2",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1"
"rxjs": "^7.8.1",
"tc-core-library-js": "appirio-tech/tc-core-library-js.git#v3.0.1"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
Expand All @@ -51,6 +55,7 @@
"eslint": "^9.18.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-prettier": "^5.2.2",
"express": "^5.1.0",
"globals": "^15.14.0",
"jest": "^29.7.0",
"prettier": "^3.4.2",
Expand All @@ -62,7 +67,8 @@
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.7.3",
"typescript-eslint": "^8.20.0"
"typescript-eslint": "^8.20.0",
"winston": "^3.17.0"
},
"prisma": {
"seed": "ts-node prisma/migrate.ts"
Expand Down
Loading