Skip to content
Open
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
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v26.5.0
v26.5.1
36 changes: 24 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# syntax=docker/dockerfile:1.7

ARG NODE_VERSION=26.5.0
ARG NODE_VERSION=26.5.1
ARG PNPM_VERSION=11.15.1

FROM node:${NODE_VERSION}-alpine AS build
FROM node:${NODE_VERSION}-alpine3.24 AS build

RUN apk upgrade --no-cache \
&& apk add --no-cache bash
Expand All @@ -17,12 +17,21 @@ RUN pnpm run build
RUN pnpm prune --prod
RUN node node_modules/prisma/build/index.js generate

FROM node:${NODE_VERSION}-alpine AS runtime
FROM alpine:3.24 AS runtime

ARG ALPINE_NODE_VERSION=26.5.1-r0
ARG OPENSSL_VERSION=3.5.8-r0

# Use Alpine's dynamically linked Node.js package so the runtime receives the
# patched system OpenSSL libraries without carrying npm or Node.js headers.
RUN apk upgrade --no-cache \
&& apk add --no-cache bash \
&& rm -rf /usr/local/lib/node_modules/npm \
&& rm -f /usr/local/bin/npm /usr/local/bin/npx
&& apk add --no-cache \
bash \
"libcrypto3=${OPENSSL_VERSION}" \
"libssl3=${OPENSSL_VERSION}" \
"nodejs-current=${ALPINE_NODE_VERSION}" \
&& addgroup -S -g 10001 app \
&& adduser -S -D -H -h /app -u 10001 -G app app

ARG RESET_DB_ARG=false
ENV RESET_DB=$RESET_DB_ARG
Expand All @@ -32,10 +41,13 @@ ENV PRISMA_CLI_BINARY_TARGETS=linux-musl-openssl-3.0.x
ENV NODE_ENV=production

WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/prisma ./prisma
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/appStartUp.sh ./appStartUp.sh
RUN chmod +x appStartUp.sh
COPY --from=build --chown=app:app /app/dist ./dist
COPY --from=build --chown=app:app /app/node_modules ./node_modules
COPY --from=build --chown=app:app /app/prisma ./prisma
COPY --from=build --chown=app:app /app/package.json ./package.json
COPY --from=build --chown=app:app /app/appStartUp.sh ./appStartUp.sh
RUN chmod 0555 appStartUp.sh

USER app

CMD ["./appStartUp.sh"]
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

Group API built on modern frameworks for managing all group-related Topcoder needs.

Use Node.js 26.5.0 and pnpm 11.15.1. Run `nvm use` in this project before running pnpm commands.
Use Node.js 26.5.1 and pnpm 11.15.1. Run `nvm use` in this project before running pnpm commands.

The production image runs as the unprivileged `app` user. Its Alpine 3.24
runtime installs Node.js 26.5.1 and the patched system OpenSSL 3.5.8 packages;
the Node.js build toolchain and npm are not copied into the runtime image.

## Project setup

Expand Down Expand Up @@ -73,15 +77,11 @@ pnpm exec prisma migrate reset
curl --request POST \
--url https://auth0proxy.topcoder-dev.com/token \
--header 'content-type: application/json' \
--data '{"auth0_url": "https://topcoder-dev.auth0.com/oauth/token", "client_id":"8uHVTW2WHp8BbBPX7J0YTAwgYbYTfjsM","client_secret":"hQXGeKO-cSZ15CLBNRDGZAGRcHWay6PAR_zTQQz4YjdX7QNU7NwGoaa3YuuUYvUv","audience":"https://m2m.topcoder-dev.com/","grant_type":"client_credentials"}'
--data '{"auth0_url": "https://topcoder-dev.auth0.com/oauth/token", "client_id":"YOUR_CLIENT_ID","client_secret":"YOUR_CLIENT_SECRET","audience":"https://m2m.topcoder-dev.com/","grant_type":"client_credentials"}'
```

For a read-only scope M2M token, use:

```
"client_id":"dgrh9mkk8N6sWsVPFf6JqdVmjjuibowf"
"client_secret":"_6jFqIppsA3u87Tm7mRDXhX_yf8-DC2ooc5f0affjuWoRiLG1ZriHtUsMQgo61qp"
```
Obtain M2M credentials with the required scope from the approved secret store;
never commit client credentials to this repository.

- then you can use Postman to test all apis
- Swagger docs are accessible at `http://localhost:3000/api-docs`
Expand Down
4 changes: 2 additions & 2 deletions doc/Group.postman_environment.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
},
{
"key": "TOKEN",
"value": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5VSkZORGd4UlRVME5EWTBOVVkzTlRkR05qTXlRamxETmpOQk5UYzVRVUV3UlRFeU56TTJRUSJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiOHVIVlRXMldIcDhCYkJQWDdKMFlUQXdnWWJZVGZqc01AY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNzUxNTEzOTY0LCJleHAiOjE3NTE2MDAzNjQsInNjb3BlIjoicmVhZDpjaGFsbGVuZ2VzIGFsbDpncm91cHMgd3JpdGU6Z3JvdXBzIHJlYWQ6Z3JvdXBzIHJlYWQ6YnVzX3RvcGljcyB3cml0ZTpidXNfYXBpIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIiwiYXpwIjoiOHVIVlRXMldIcDhCYkJQWDdKMFlUQXdnWWJZVGZqc00ifQ.pdVpeB0PIZSFpTjcR82AvMiyFQizj04y7x7zqU2Y9Ao_ZjlwmcjDk02WgZrPzhgJ_59E5M9ZCgEyFGA3EZrzMKcUcyDDcL-PhN6l5-IMBYDyGYNh7gLuyY5vwMqGUZx3IC7mwLXMeNtenbigkbOx00AHI9R85g2Rqmi6wKnDHsGCFfNKckPBpdCCom-PHoxkkLEcCAedvcXDX8AUkIePJORfaoC5ZEV0aI0-miU1fUwqQMySZX891Hu7cDL5KxZY12ic_SNgoQ_vEi3yw5hbrl7urkmg1HyFxlb0tX7cQmgvVXqxwlaqgrBEv9UOB-vcwIqsWLJRKSJ1OA7abg5NXA",
"value": "YOUR_JWT_TOKEN",
"enabled": true
}
],
"_postman_variable_scope": "environment",
"_postman_exported_at": "2025-07-07T14:54:50.195Z",
"_postman_exported_using": "Postman/9.28.4"
}
}
3 changes: 1 addition & 2 deletions mock/mock-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ app.post('/eventBus/bus/events', (req, res) => {
res.json({})
})

const m2mToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3RvcGNvZGVyLWRldi5hdXRoMC5jb20vIiwic3ViIjoiakdJZjJwZDNmNDRCMWpxdk9haTMwQklLVFphbllCZlVAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbTJtLnRvcGNvZGVyLWRldi5jb20vIiwiaWF0IjoxNzQ4MDk5NDk4LCJleHAiOjE4NDgxODU4OTgsInNjb3BlIjoid3JpdGU6YnVzX2FwaSxhbGw6Y2hhbGxlbmdlcyIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyIsImF6cCI6ImpHSWYycGQzZjQ0QjFqcXZPYWkzMEJJS1RaYW5ZQmZVIn0.h3ksdsdJm5USGF1VgROrpkTtStmCzv5ZA6y8bd8AnGY';
const m2mToken = 'MOCK_M2M_TOKEN';

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

Expand Down Expand Up @@ -111,4 +111,3 @@ app.get('/challenges', (req, res) => {
app.listen(app.get('port'), '0.0.0.0', () => {
logger.info(`Express server listening on port ${app.get('port')}`)
})

82 changes: 43 additions & 39 deletions pnpm-lock.yaml

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

13 changes: 8 additions & 5 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,24 @@ overrides:
'ajv@^8.0.0': 8.20.0
axios: 1.18.1
'body-parser@^2': 2.3.0
'brace-expansion@^1.0.0': 1.1.16
'brace-expansion@^2.0.0': 2.1.2
'brace-expansion@^1.0.0': 1.1.18
'brace-expansion@^2.0.0': 2.1.4
'brace-expansion@^5.0.0': 5.0.9
deepmerge-ts: 8.0.0
defu: 6.1.7
'diff@^4': 4.0.4
'effect@^3.0.0': 3.22.0
'fast-uri@^3.0.0': 3.1.4
'fast-uri@^3.0.0': 3.1.5
'file-type@>=13.0.0 <21.3.2': 21.3.2
flatted: 3.4.2
follow-redirects: 1.16.0
form-data: 4.0.6
handlebars: 4.7.9
'ip-address@^10.0.0': 10.1.1
'joi@^18.0.0': 18.2.1
'js-yaml@^3': 3.15.0
'js-yaml@^4.0.0': 4.3.0
'js-yaml@^3': 3.15.1
'js-yaml@^4.0.0': 4.3.1
'js-yaml@>=5.0.0 <=5.2.1': 5.2.2
jws: 4.0.1
lodash: 4.18.1
'minimatch@^3.0.0': 3.1.4
Expand Down
Loading