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
3 changes: 3 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
- name: Check for known vulnerabilities in backend (production dependencies)
run: npm audit --workspace=backend --omit=dev --audit-level=critical

- name: Verify security setup
run: npm run verify-security

codeql-analysis:
name: CodeQL Analysis
runs-on: ubuntu-latest
Expand Down
12 changes: 8 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ We take the security of FlowFi seriously. If you discover a security vulnerabili

**Please do not report security vulnerabilities through public GitHub issues.**

Instead, please report security vulnerabilities by:
The preferred and fastest way to report a vulnerability is **GitHub Security Advisories**:

1. **Email**: Send details to `security@flowfi.dev` (if available) or create a private security advisory on GitHub
2. **GitHub Security Advisory**: Use GitHub's [private vulnerability reporting](https://github.com/LabsCrypt/flowfi/security/advisories/new) feature
3. **Direct Contact**: Reach out to the maintainers directly through GitHub
1. Go to the [Security tab](https://github.com/LabsCrypt/flowfi/security) of this repository.
2. Click **"Report a vulnerability"** (or use the direct link: [Report a vulnerability](https://github.com/LabsCrypt/flowfi/security/advisories/new)).
3. Fill in the private advisory form with as much detail as possible (see "What to Include" below).

This opens a private channel between you and the maintainers — nothing is visible publicly until we agree on a disclosure timeline.

If you cannot use GitHub Security Advisories for any reason, you may instead reach out to the maintainers directly through the [community Telegram](https://t.me/+DOylgFv1jyJlNzM0) and request a private contact, or send a message via GitHub Discussions asking to be contacted privately (do not include vulnerability details in the public message).

### What to Include

Expand Down
11 changes: 11 additions & 0 deletions docs/api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# API Collections

This directory contains hand-maintained Postman/Hoppscotch collections for exploring the FlowFi API.

**Source of truth:** [`backend/src/config/swagger.ts`](../../backend/src/config/swagger.ts) and the `@openapi` JSDoc annotations on each route. The generated spec is served live at `http://localhost:3001/api-docs` (UI) and `http://localhost:3001/api-docs.json` (raw OpenAPI JSON).

`flowfi.postman_collection.json` and `flowfi.hoppscotch_collection.json` are convenience collections for manual testing — they are not generated from the OpenAPI spec and can drift. When routes change:

1. Update the `@openapi` annotations on the affected route/controller first.
2. Re-check the endpoints in this directory's collections against `http://localhost:3001/api-docs.json` and update paths, methods, and bodies to match.
3. If a collection and the Swagger spec ever disagree, the Swagger spec wins.
100 changes: 100 additions & 0 deletions docs/api/flowfi.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,106 @@
"body": "{\n \"streamId\": 1,\n \"claimableAmount\": \"5000\",\n \"actionable\": true,\n \"calculatedAt\": \"2024-02-21T14:30:00.000Z\",\n \"cached\": false\n}"
}
]
},
{
"name": "Get user stream summary",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/v1/streams/summary/{{senderPublicKey}}",
"host": ["{{baseUrl}}"],
"path": ["v1", "streams", "summary", "{{senderPublicKey}}"]
},
"description": "Get an aggregated stream summary for a Stellar public key."
},
"response": []
},
{
"name": "Pause stream",
"request": {
"method": "POST",
"header": [
{ "key": "Authorization", "value": "Bearer {{authToken}}" }
],
"url": {
"raw": "{{baseUrl}}/v1/streams/{{streamId}}/pause",
"host": ["{{baseUrl}}"],
"path": ["v1", "streams", "{{streamId}}", "pause"]
},
"description": "Pause an active stream. Only the sender can pause their own stream."
},
"response": []
},
{
"name": "Resume stream",
"request": {
"method": "POST",
"header": [
{ "key": "Authorization", "value": "Bearer {{authToken}}" }
],
"url": {
"raw": "{{baseUrl}}/v1/streams/{{streamId}}/resume",
"host": ["{{baseUrl}}"],
"path": ["v1", "streams", "{{streamId}}", "resume"]
},
"description": "Resume a paused stream. Only the sender can resume their own stream."
},
"response": []
},
{
"name": "Withdraw from stream",
"request": {
"method": "POST",
"header": [
{ "key": "Authorization", "value": "Bearer {{authToken}}" }
],
"url": {
"raw": "{{baseUrl}}/v1/streams/{{streamId}}/withdraw",
"host": ["{{baseUrl}}"],
"path": ["v1", "streams", "{{streamId}}", "withdraw"]
},
"description": "Withdraw the currently claimable amount. Only the recipient can withdraw."
},
"response": []
},
{
"name": "Cancel stream",
"request": {
"method": "POST",
"header": [
{ "key": "Authorization", "value": "Bearer {{authToken}}" }
],
"url": {
"raw": "{{baseUrl}}/v1/streams/{{streamId}}/cancel",
"host": ["{{baseUrl}}"],
"path": ["v1", "streams", "{{streamId}}", "cancel"]
},
"description": "Cancel an active stream. Only the original sender can cancel. Accrued tokens go to the recipient, remainder is refunded to the sender."
},
"response": []
},
{
"name": "Top up stream",
"request": {
"method": "POST",
"header": [
{ "key": "Content-Type", "value": "application/json" },
{ "key": "Authorization", "value": "Bearer {{authToken}}" }
],
"body": {
"mode": "raw",
"raw": "{\n \"amount\": \"5000\"\n}",
"options": { "raw": { "language": "json" } }
},
"url": {
"raw": "{{baseUrl}}/v1/streams/{{streamId}}/top-up",
"host": ["{{baseUrl}}"],
"path": ["v1", "streams", "{{streamId}}", "top-up"]
},
"description": "Add additional funds to an existing active stream. Only the original sender can top up."
},
"response": []
}
]
},
Expand Down
Loading