From 5d2b7c62de2eea8ffce3ee27c6842fb6499d338f Mon Sep 17 00:00:00 2001 From: VasuS609 Date: Mon, 6 Oct 2025 15:01:54 +0530 Subject: [PATCH 1/2] docs: update README, .gitignore, and appwrite.json for clarity and security --- .gitignore | 4 ++- README.md | 38 ++++++++++++++++++++++---- appwrite.json | 4 +-- functions/create-room/src/main.js | 1 + functions/database-cleaner/src/main.js | 1 + functions/delete-room/src/main.js | 1 + functions/join-room/src/main.js | 1 + functions/livekit-webhook/src/main.js | 1 + functions/match-maker/src/main.js | 1 + functions/send-otp/src/main.js | 1 + functions/verify-email/src/main.js | 2 +- functions/verify-otp/src/main.js | 1 + 12 files changed, 47 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index c39a475..07a73e3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ appwrite/ **/.env **/node_modules/ **/resonate-service-account.json -meili_data/ \ No newline at end of file +meili_data/ +/.env +/node_modules/ \ No newline at end of file diff --git a/README.md b/README.md index a8c84d1..0fd2ce1 100644 --- a/README.md +++ b/README.md @@ -7,17 +7,45 @@ Go to [this repository](https://github.com/AOSSIE-Org/Resonate) to know more about the project. -## Environment Setup : +## Environment Setup -1. Pre-requisites : +1. Pre-requisites (a) Fork the Repo - (b) Clone the Repo : `git clone https://github.com/AOSSIE-Org/Resonate-Backend` + (b) Clone the Repo: `git clone https://github.com/AOSSIE-Org/Resonate-Backend` -2. Follow [this guide](https://docs.livekit.io/cloud/project-management/keys-and-tokens/) to obtain your `HOST`, `API-KEY`, `API-SECRET` from [livekit-cloud](https://livekit.io/cloud). +2. Set up environment variables -3. Create a new project on [Appwrite Cloud](https://appwrite.io/) or self host it locally by pulling their [docker image](https://appwrite.io/docs/self-hosting). Know more about Appwrite [here](https://appwrite.io/docs). +```bash +cp .env.example .env +``` + +Then fill in the values in `.env`: + - Leave the database/collection IDs as they are (they match the project structure) + - Add your Livekit credentials (see step 3) + - Add your email credentials (see step 5) + +3. Obtain Livekit credentials + +- Follow this guide to get your credentials. +- Add `LIVEKIT_HOST`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET` to your `.env` file. + +4. Set up Appwrite + +- Create a project on Appwrite Cloud or self-host. +- Create an API key with necessary scopes. +- Import the database structure: `appwrite deploy collection`. +- Copy the generated database and collection IDs into your `.env` file. + +5. Email configuration (for OTP functionality) + +- Set `SENDER_MAIL` to your email address. +- Set `SENDER_PASSWORD` to your app password (Gmail guide). + +6. Security note + +- Do not hardcode secrets in `appwrite.json`. Use environment variables. The template `.env.example` lists all variables required across functions. ## Functions : diff --git a/appwrite.json b/appwrite.json index 7569a7d..6c1d5a9 100644 --- a/appwrite.json +++ b/appwrite.json @@ -85,7 +85,7 @@ "vars": [ { "key": "SENDER_MAIL", - "value": "aossieorgforu@gmail.com" + "value": "$SENDER_MAIL" }, { "key": "VERIFICATION_DATABASE_ID", @@ -93,7 +93,7 @@ }, { "key": "SENDER_PASSWORD", - "value": "xizkyvzhduejxjel" + "value": "$SENDER_PASSWORD" }, { "key": "OTP_COLLECTION_ID", diff --git a/functions/create-room/src/main.js b/functions/create-room/src/main.js index 7a1e63b..0722812 100644 --- a/functions/create-room/src/main.js +++ b/functions/create-room/src/main.js @@ -5,6 +5,7 @@ import { throwIfMissing } from "./utils.js"; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ "APPWRITE_API_KEY", + "APPWRITE_FUNCTION_PROJECT_ID", "MASTER_DATABASE_ID", "ROOMS_COLLECTION_ID", "LIVEKIT_HOST", diff --git a/functions/database-cleaner/src/main.js b/functions/database-cleaner/src/main.js index 8c397dc..f7b2748 100644 --- a/functions/database-cleaner/src/main.js +++ b/functions/database-cleaner/src/main.js @@ -4,6 +4,7 @@ import { throwIfMissing } from "./utils.js"; export default async (context) => { throwIfMissing(process.env, [ "APPWRITE_API_KEY", + "APPWRITE_FUNCTION_PROJECT_ID", "ROOMS_COLLECTION_ID", "PARTICIPANTS_COLLECTION_ID", "ACTIVE_PAIRS_COLLECTION_ID", diff --git a/functions/delete-room/src/main.js b/functions/delete-room/src/main.js index 67a8c0d..3786e9d 100644 --- a/functions/delete-room/src/main.js +++ b/functions/delete-room/src/main.js @@ -5,6 +5,7 @@ import { throwIfMissing } from "./utils.js"; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ "APPWRITE_API_KEY", + "APPWRITE_FUNCTION_PROJECT_ID", "MASTER_DATABASE_ID", "ROOMS_COLLECTION_ID", "PARTICIPANTS_COLLECTION_ID", diff --git a/functions/join-room/src/main.js b/functions/join-room/src/main.js index c959c3f..6364d5e 100644 --- a/functions/join-room/src/main.js +++ b/functions/join-room/src/main.js @@ -3,6 +3,7 @@ import { throwIfMissing } from "./utils.js"; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ + "APPWRITE_FUNCTION_PROJECT_ID", "LIVEKIT_API_KEY", "LIVEKIT_API_SECRET", "LIVEKIT_SOCKET_URL", diff --git a/functions/livekit-webhook/src/main.js b/functions/livekit-webhook/src/main.js index 5ac26bb..8ea135b 100644 --- a/functions/livekit-webhook/src/main.js +++ b/functions/livekit-webhook/src/main.js @@ -7,6 +7,7 @@ export default async (context) => { throwIfMissing(process.env, [ 'APPWRITE_API_KEY', + 'APPWRITE_FUNCTION_PROJECT_ID', 'MASTER_DATABASE_ID', 'ROOMS_COLLECTION_ID', 'PARTICIPANTS_COLLECTION_ID', diff --git a/functions/match-maker/src/main.js b/functions/match-maker/src/main.js index d578cae..d2f1029 100644 --- a/functions/match-maker/src/main.js +++ b/functions/match-maker/src/main.js @@ -4,6 +4,7 @@ import { throwIfMissing } from './utils.js'; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ 'APPWRITE_API_KEY', + 'APPWRITE_FUNCTION_PROJECT_ID', 'DATABASE_ID', 'REQUESTS_COLLECTION_ID', 'ACTIVE_PAIRS_COLLECTION_ID', diff --git a/functions/send-otp/src/main.js b/functions/send-otp/src/main.js index 9449abc..a091def 100644 --- a/functions/send-otp/src/main.js +++ b/functions/send-otp/src/main.js @@ -6,6 +6,7 @@ import { randomInt } from "node:crypto"; // for generating cryptographically sec export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ "APPWRITE_API_KEY", + "APPWRITE_FUNCTION_PROJECT_ID", "VERIFICATION_DATABASE_ID", "OTP_COLLECTION_ID", "SENDER_MAIL", diff --git a/functions/verify-email/src/main.js b/functions/verify-email/src/main.js index 963a241..16ae703 100644 --- a/functions/verify-email/src/main.js +++ b/functions/verify-email/src/main.js @@ -2,7 +2,7 @@ import { Client, Users } from 'node-appwrite'; import { throwIfMissing } from './utils.js'; export default async ({ req, res, log, error }) => { - throwIfMissing(process.env, ['APPWRITE_API_KEY']); + throwIfMissing(process.env, ['APPWRITE_API_KEY', 'APPWRITE_FUNCTION_PROJECT_ID']); const client = new Client() .setEndpoint( diff --git a/functions/verify-otp/src/main.js b/functions/verify-otp/src/main.js index 96375fb..ba88bbb 100644 --- a/functions/verify-otp/src/main.js +++ b/functions/verify-otp/src/main.js @@ -4,6 +4,7 @@ import { throwIfMissing } from './utils.js'; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ 'APPWRITE_API_KEY', + 'APPWRITE_FUNCTION_PROJECT_ID', 'VERIFICATION_DATABASE_ID', 'OTP_COLLECTION_ID', 'VERIFY_COLLECTION_ID', From b0c67298e520780749312e1f2a9bb5e190f930fb Mon Sep 17 00:00:00 2001 From: VasuS609 Date: Mon, 6 Oct 2025 16:56:07 +0530 Subject: [PATCH 2/2] Address review feedback: fix breaking changes, add missing docs --- .env.example | 36 ++++++++++++++++++++++++ .gitignore | 4 +-- README.md | 39 +++++++++++++++++++------- appwrite.json | 4 +-- functions/create-room/src/main.js | 1 - functions/database-cleaner/src/main.js | 1 - functions/delete-room/src/main.js | 1 - functions/join-room/src/main.js | 1 - functions/livekit-webhook/src/main.js | 1 - functions/send-otp/src/main.js | 1 - functions/verify-email/src/main.js | 2 +- functions/verify-otp/src/main.js | 1 - 12 files changed, 69 insertions(+), 23 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..15722d4 --- /dev/null +++ b/.env.example @@ -0,0 +1,36 @@ +# Appwrite Configuration +APPWRITE_API_KEY= +APPWRITE_FUNCTION_PROJECT_ID=resonate +APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1 + +# Livekit Configuration +LIVEKIT_HOST= +LIVEKIT_API_KEY= +LIVEKIT_API_SECRET= + +# Email Configuration (for OTP) +SENDER_MAIL= +SENDER_PASSWORD= + +# Database IDs +VERIFICATION_DATABASE_ID=64a7bfd6b09121548bfe +OTP_COLLECTION_ID=64a7bfe3a3a7ee5bf7f8 +VERIFY_COLLECTION_ID=64a7c0100eabfe8d3844 +MASTER_DATABASE_ID=64a521785f5be62b796f +ROOMS_COLLECTION_ID=64a5217e695bf2c4ec9c +PARTICIPANTS_COLLECTION_ID=64a63e508145d1084abf +ACTIVE_PAIRS_COLLECTION_ID=64d980cd65ff2e08ab97 +REQUESTS_COLLECTION_ID=64d980211f1395263ebe +DATABASE_ID=64a521785f5be62b796f + +# Upcoming Rooms +UPCOMING_ROOMS_DATABASE_ID=6522fcf27a1bbc4238df +UPCOMING_ROOMS_COLLECTION_ID=6522fd163103bd453183 +SUBSCRIBER_COLLECTION_ID=6522fd267db6fdad3392 + +# User Data +USER_DATA_DATABASE_ID=64a1319104a149e16f5c +USERS_COLLECTION_ID=64a52f0a6c41ded09def + +# Database Cleaner +RETENTION_PERIOD_DAYS=0 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 07a73e3..c39a475 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,4 @@ appwrite/ **/.env **/node_modules/ **/resonate-service-account.json -meili_data/ -/.env -/node_modules/ \ No newline at end of file +meili_data/ \ No newline at end of file diff --git a/README.md b/README.md index 0fd2ce1..c4293f0 100644 --- a/README.md +++ b/README.md @@ -15,37 +15,56 @@ Go to [this repository](https://github.com/AOSSIE-Org/Resonate) to know more abo (b) Clone the Repo: `git clone https://github.com/AOSSIE-Org/Resonate-Backend` -2. Set up environment variables +2. Follow this guide to obtain your Livekit credentials + +- Guide: https://docs.livekit.io/cloud/project-management/keys-and-tokens/ +- You will need `LIVEKIT_HOST`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET`. + +3. Set up environment variables ```bash cp .env.example .env ``` -Then fill in the values in `.env`: - - Leave the database/collection IDs as they are (they match the project structure) - - Add your Livekit credentials (see step 3) - - Add your email credentials (see step 5) +Windows: + +```powershell +Copy-Item .env.example .env +``` + +or (CMD): -3. Obtain Livekit credentials +```cmd +copy .env.example .env +``` -- Follow this guide to get your credentials. -- Add `LIVEKIT_HOST`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET` to your `.env` file. +Then fill in the values in `.env`: +- Leave the database/collection IDs as they are (they match the project structure) +- Add your Livekit credentials (see step 2) +- Add your email credentials (see step 5) 4. Set up Appwrite -- Create a project on Appwrite Cloud or self-host. +- Create a new project on [Appwrite Cloud](https://appwrite.io/) or self host it locally by pulling their [docker image](https://appwrite.io/docs/self-hosting). Know more about Appwrite [here](https://appwrite.io/docs). - Create an API key with necessary scopes. - Import the database structure: `appwrite deploy collection`. - Copy the generated database and collection IDs into your `.env` file. +- Important: Appwrite functions do not read from your local `.env`. You must set function variables in Appwrite: + - Console: Go to Project → Functions → Select a function → Settings → Variables → add keys/values. + - CLI example: + - `appwrite client --endpoint https://cloud.appwrite.io/v1 --projectId --key ` + - `appwrite functions update --functionId --vars APPWRITE_API_KEY=<...>,VERIFICATION_DATABASE_ID=<...>,OTP_COLLECTION_ID=<...>,SENDER_MAIL=<...>,SENDER_PASSWORD=<...>` 5. Email configuration (for OTP functionality) - Set `SENDER_MAIL` to your email address. -- Set `SENDER_PASSWORD` to your app password (Gmail guide). +- Set `SENDER_PASSWORD` to your app password (Gmail guide: https://support.google.com/accounts/answer/185833?hl=en). 6. Security note - Do not hardcode secrets in `appwrite.json`. Use environment variables. The template `.env.example` lists all variables required across functions. +- Note: `appwrite.json` does not read from `.env`. Set function variables in the Appwrite Console (or via Appwrite CLI) for cloud execution; `.env` is for local configuration/reference. +- Tip: Keep `.env` as a convenient record of values; replicate them into Appwrite Function Variables for actual use. ## Functions : diff --git a/appwrite.json b/appwrite.json index 6c1d5a9..870ec71 100644 --- a/appwrite.json +++ b/appwrite.json @@ -85,7 +85,7 @@ "vars": [ { "key": "SENDER_MAIL", - "value": "$SENDER_MAIL" + "value": "" }, { "key": "VERIFICATION_DATABASE_ID", @@ -93,7 +93,7 @@ }, { "key": "SENDER_PASSWORD", - "value": "$SENDER_PASSWORD" + "value": "" }, { "key": "OTP_COLLECTION_ID", diff --git a/functions/create-room/src/main.js b/functions/create-room/src/main.js index 0722812..7a1e63b 100644 --- a/functions/create-room/src/main.js +++ b/functions/create-room/src/main.js @@ -5,7 +5,6 @@ import { throwIfMissing } from "./utils.js"; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ "APPWRITE_API_KEY", - "APPWRITE_FUNCTION_PROJECT_ID", "MASTER_DATABASE_ID", "ROOMS_COLLECTION_ID", "LIVEKIT_HOST", diff --git a/functions/database-cleaner/src/main.js b/functions/database-cleaner/src/main.js index f7b2748..8c397dc 100644 --- a/functions/database-cleaner/src/main.js +++ b/functions/database-cleaner/src/main.js @@ -4,7 +4,6 @@ import { throwIfMissing } from "./utils.js"; export default async (context) => { throwIfMissing(process.env, [ "APPWRITE_API_KEY", - "APPWRITE_FUNCTION_PROJECT_ID", "ROOMS_COLLECTION_ID", "PARTICIPANTS_COLLECTION_ID", "ACTIVE_PAIRS_COLLECTION_ID", diff --git a/functions/delete-room/src/main.js b/functions/delete-room/src/main.js index 3786e9d..67a8c0d 100644 --- a/functions/delete-room/src/main.js +++ b/functions/delete-room/src/main.js @@ -5,7 +5,6 @@ import { throwIfMissing } from "./utils.js"; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ "APPWRITE_API_KEY", - "APPWRITE_FUNCTION_PROJECT_ID", "MASTER_DATABASE_ID", "ROOMS_COLLECTION_ID", "PARTICIPANTS_COLLECTION_ID", diff --git a/functions/join-room/src/main.js b/functions/join-room/src/main.js index 6364d5e..c959c3f 100644 --- a/functions/join-room/src/main.js +++ b/functions/join-room/src/main.js @@ -3,7 +3,6 @@ import { throwIfMissing } from "./utils.js"; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ - "APPWRITE_FUNCTION_PROJECT_ID", "LIVEKIT_API_KEY", "LIVEKIT_API_SECRET", "LIVEKIT_SOCKET_URL", diff --git a/functions/livekit-webhook/src/main.js b/functions/livekit-webhook/src/main.js index 8ea135b..5ac26bb 100644 --- a/functions/livekit-webhook/src/main.js +++ b/functions/livekit-webhook/src/main.js @@ -7,7 +7,6 @@ export default async (context) => { throwIfMissing(process.env, [ 'APPWRITE_API_KEY', - 'APPWRITE_FUNCTION_PROJECT_ID', 'MASTER_DATABASE_ID', 'ROOMS_COLLECTION_ID', 'PARTICIPANTS_COLLECTION_ID', diff --git a/functions/send-otp/src/main.js b/functions/send-otp/src/main.js index a091def..9449abc 100644 --- a/functions/send-otp/src/main.js +++ b/functions/send-otp/src/main.js @@ -6,7 +6,6 @@ import { randomInt } from "node:crypto"; // for generating cryptographically sec export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ "APPWRITE_API_KEY", - "APPWRITE_FUNCTION_PROJECT_ID", "VERIFICATION_DATABASE_ID", "OTP_COLLECTION_ID", "SENDER_MAIL", diff --git a/functions/verify-email/src/main.js b/functions/verify-email/src/main.js index 16ae703..963a241 100644 --- a/functions/verify-email/src/main.js +++ b/functions/verify-email/src/main.js @@ -2,7 +2,7 @@ import { Client, Users } from 'node-appwrite'; import { throwIfMissing } from './utils.js'; export default async ({ req, res, log, error }) => { - throwIfMissing(process.env, ['APPWRITE_API_KEY', 'APPWRITE_FUNCTION_PROJECT_ID']); + throwIfMissing(process.env, ['APPWRITE_API_KEY']); const client = new Client() .setEndpoint( diff --git a/functions/verify-otp/src/main.js b/functions/verify-otp/src/main.js index ba88bbb..96375fb 100644 --- a/functions/verify-otp/src/main.js +++ b/functions/verify-otp/src/main.js @@ -4,7 +4,6 @@ import { throwIfMissing } from './utils.js'; export default async ({ req, res, log, error }) => { throwIfMissing(process.env, [ 'APPWRITE_API_KEY', - 'APPWRITE_FUNCTION_PROJECT_ID', 'VERIFICATION_DATABASE_ID', 'OTP_COLLECTION_ID', 'VERIFY_COLLECTION_ID',