diff --git a/.env_test b/.env_test new file mode 100644 index 0000000000..a073643e02 --- /dev/null +++ b/.env_test @@ -0,0 +1,29 @@ +IMAGE_SIZE_LIMIT_KB=20000 +NODE_ENV=development +SERVER_PORT= +ACCESS_TOKEN_SECRET=97220622309b85aef016a5fa7597988946a799616040ef9d2914c7d82384f396 +REFRESH_TOKEN_SECRET=5de257b9fa136179e07ea0d3e0d37f1c5d764a82eb1d4a640ce752b8b37d7d2a +MONGO_DB_URL= +RECAPTCHA_SECRET_KEY=valid-secret-key-test +MAIL_USERNAME=testemail@testing.com +MAIL_PASSWORD=testPassword +IS_SMTP= +SMTP_HOST= +SMTP_PASSWORD= +SMTP_USERNAME= +SMTP_PORT= +SMTP_SSL_TLS= +LOG=false +LOG_PATH=./logs/transaction.log +LAST_RESORT_SUPERADMIN_EMAIL=testemail@test.com +COLORIZE_LOGS=false +LOG_LEVEL=info +REDIS_HOST=test +REDIS_PORT=6378 +REDIS_PASSWORD= +MINIO_ENDPOINT= +MINIO_ROOT_USER= +MINIO_ROOT_PASSWORD= +MINIO_BUCKET= +MINIO_DATA_DIR= +PWD=. diff --git a/certs/cert.pem b/certs/cert.pem new file mode 100644 index 0000000000..d5ce8c095b --- /dev/null +++ b/certs/cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjzCCAnegAwIBAgIUcnWuJog1MoQVbX4GJPFx+GyUOAowDQYJKoZIhvcNAQEL +BQAwVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5 +MRUwEwYDVQQKDAxPcmdhbml6YXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0y +NTAxMDYxODE2MjRaFw0yNTAxMDcxODE2MjRaMFcxCzAJBgNVBAYTAlVTMQ4wDAYD +VQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEVMBMGA1UECgwMT3JnYW5pemF0aW9u +MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC69NGgJ3b1TuL+tTVZSAduRkFsNMoByLmtV3UoHo3KFYcdcFq0/7ga+sJM +Ms7UCZF7irVCRsaSPj1cmGdx+cnx9XgFSk5TSuWMyfMnytI61isGfoupWNJpHmlJ +j2NwyhHVF3MCoWO/TfJkOIUmgy2TS74PQgYCBz5a6cXS71dFYojMr15MHp1XdyRj +40UHbt3e9vJs0N/lNygxw6hmzWsyuVHlja2uGzgb/SDPEa7dUVV287IOt9EqlghE +Jgb6kQ/VqgANLbDtOQe2K+KOjxhHmGSrnFfcTHfsxzAW3F/6xskzgOJNqursNnzt +8kbN/r+Tf+AO66CmVv0GNDKepRq3AgMBAAGjUzBRMB0GA1UdDgQWBBTWGsWmcNqT +Ow2Ul5WNVy10EXyhmjAfBgNVHSMEGDAWgBTWGsWmcNqTOw2Ul5WNVy10EXyhmjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBeKgA0GzAZpSpsOYgF +Cj2FQHvd9z4HXM1/qxqpBnl1zaaAK0BbBoV3lPcDPyTRbuLjO0ItscrXTOhP++Jz +9xcSBwZOiTHYjGL95ARYQjGFmoxwM3ixs1f9QXeAFpSSS5qNzrN95w0GXPZvO99a +LW4IE40KtfFoQf1K0jlqBYc9U5W/UwzRF1NVkSwyx63g5MejFv2xZd4RJY85ayIV +Nk2FmM3USPdWaKrmO8QjId0r6s3J0l7Ded31frodTogxGAdJseD+t1/Z5K+MDRoE +LZ3/is5pDL26I+EJCKeWMQC5qLY2eXusA0VOu18TdHItMHx9fOEFrOcSt9fh8XSQ +Rsd9 +-----END CERTIFICATE----- diff --git a/certs/key.pem b/certs/key.pem new file mode 100644 index 0000000000..c09feab3d2 --- /dev/null +++ b/certs/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC69NGgJ3b1TuL+ +tTVZSAduRkFsNMoByLmtV3UoHo3KFYcdcFq0/7ga+sJMMs7UCZF7irVCRsaSPj1c +mGdx+cnx9XgFSk5TSuWMyfMnytI61isGfoupWNJpHmlJj2NwyhHVF3MCoWO/TfJk +OIUmgy2TS74PQgYCBz5a6cXS71dFYojMr15MHp1XdyRj40UHbt3e9vJs0N/lNygx +w6hmzWsyuVHlja2uGzgb/SDPEa7dUVV287IOt9EqlghEJgb6kQ/VqgANLbDtOQe2 +K+KOjxhHmGSrnFfcTHfsxzAW3F/6xskzgOJNqursNnzt8kbN/r+Tf+AO66CmVv0G +NDKepRq3AgMBAAECggEAOMOdpEVnQosts81cQdvzWaGeOpb6oLkL21w7F6/TOED6 +Ec+r0tnz0clCVjV1A/9Vu099wn5Py1Z3dhZWDk6b6Mmxo9WQW4zZjrpAiFv2IeQm +EyY4DHaKCF2x9SJCvJu191/TzUAoU4z8pD5e+zcIDvmH3wUaYuJFJgBlzqpZ8pg3 +jedWQy7bIFAsAYfrF5RQ6psgjlvL/nje1/1XPdmtlk+rJW9z8xAbeiFBuizHE6Bj +Y4x0XYHC/QEP+1RHS3udvZGZ4HciaJXPSMW+S2+mose54SuQ9n5b2SSMQCp5Mccq +wdWSFaP3GyhSSvmR8Eklp1p64G2GXa7cZdrSmKhY2QKBgQDJ01Y633btrj+MI4Ds +z1WSInEU7dra5XQ2hCaYbeanXT25uJSJtOaScjmgCjer0Qf84cXlu6WAKBcfSnQJ +oMPhv19oeskEMCDR/8oQrLA5V++nA+JoJSb9hRHaKSbs42DA8g6vtEnX/btQVkSm +u6fbdBGfXpi2MNzBztAKg/qLPwKBgQDtI7pVYU5ql21UNfbY2k/gfGUyuorFGaKl +6pEgedntHMJ4Sae0Z8uC7iPDUMfoPpCEQTjWcYw8BEBOx6IRN8YggWCutzUHn2e0 +xNyUYKIMm9zjY/I7snJJNU2wFE7m8lDuxqLf4QgjsyxPgvKT8q1E+qdNBXYSqqwq +ugq3wHfqiQKBgFGWQkyIW25Xu06uZ4bThdcOX0JDqO5GRYVoRKXn/472rWYvjLRi +Ubcvv8XHe5vUY3NB3ZsyEQROsJIwqdneiHDwyOPWhv5PamUaDxhQhuiXeMS+WD8b +jbh8m6viaN7oSAuXjoJO0m8jHh6q0RPJ1mBrelg/iGJWPFeIgCdQFO9HAoGAfEcf +HiPS3tXhPCLT7S3scq9+salFlKosrVtTF3wEk9lgqX2gYFGNPF7lazTor3QqdMVh +rjDv13w6346MBw39zYdAThBBwG7wALKzDyfdhVIh3yHADz0j2+4NetwJxcr0U07S +iRX8GAmMjVcJHjQuTlo2V40nJf1AIVxCxa4eqlECgYEAiXepBWrTigoFdOf6Jv0P +AUyYdf5pb8EPDMr+vsA7ZmQH+vg9AgWiWlp16SgAX4h9qn1/I52Sdov5ihQEgl3r +M+XZzvSFYGxdrwbn1nKvX51/4ieKUy6dsrpFE/FYwepg/Ekztn7HcdK7dlkFdoQB +1Po0a9g7bexahOWqkR469QQ= +-----END PRIVATE KEY----- diff --git a/data/.minio.sys/format.json b/data/.minio.sys/format.json new file mode 100644 index 0000000000..a6ef3e8e06 --- /dev/null +++ b/data/.minio.sys/format.json @@ -0,0 +1 @@ +{"version":"1","format":"xl-single","id":"893a4950-2c9f-4915-9d4e-bd90c4cd840e","xl":{"version":"3","this":"776fcaee-89a1-4336-b54b-65f914c0889e","sets":[["776fcaee-89a1-4336-b54b-65f914c0889e"]],"distributionAlgo":"SIPMOD+PARITY"}} \ No newline at end of file diff --git a/data/.minio.sys/tmp/.trash/46d9f01f-5d55-43c3-bf32-f6a3e6c2649d/xl.meta.bkp b/data/.minio.sys/tmp/.trash/46d9f01f-5d55-43c3-bf32-f6a3e6c2649d/xl.meta.bkp new file mode 100644 index 0000000000..c2ece661cf Binary files /dev/null and b/data/.minio.sys/tmp/.trash/46d9f01f-5d55-43c3-bf32-f6a3e6c2649d/xl.meta.bkp differ diff --git a/data/.minio.sys/tmp/.trash/4cae81ed-7957-404f-8e43-b60fddd34bbf/xl.meta.bkp b/data/.minio.sys/tmp/.trash/4cae81ed-7957-404f-8e43-b60fddd34bbf/xl.meta.bkp new file mode 100644 index 0000000000..9474f5c4ae Binary files /dev/null and b/data/.minio.sys/tmp/.trash/4cae81ed-7957-404f-8e43-b60fddd34bbf/xl.meta.bkp differ diff --git a/data/.minio.sys/tmp/.trash/78bf3dd5-3c3f-47e4-afa0-e3884d98b8b7/xl.meta.bkp b/data/.minio.sys/tmp/.trash/78bf3dd5-3c3f-47e4-afa0-e3884d98b8b7/xl.meta.bkp new file mode 100644 index 0000000000..637d0cd22e Binary files /dev/null and b/data/.minio.sys/tmp/.trash/78bf3dd5-3c3f-47e4-afa0-e3884d98b8b7/xl.meta.bkp differ diff --git a/data/.minio.sys/tmp/.trash/8384d4cb-9be3-4a8e-9a7f-a8513dc1664f/xl.meta.bkp b/data/.minio.sys/tmp/.trash/8384d4cb-9be3-4a8e-9a7f-a8513dc1664f/xl.meta.bkp new file mode 100644 index 0000000000..9a27f98a25 Binary files /dev/null and b/data/.minio.sys/tmp/.trash/8384d4cb-9be3-4a8e-9a7f-a8513dc1664f/xl.meta.bkp differ diff --git a/data/.minio.sys/tmp/.trash/99633b28-5c1c-4f9e-93bc-0d113c01e530/xl.meta.bkp b/data/.minio.sys/tmp/.trash/99633b28-5c1c-4f9e-93bc-0d113c01e530/xl.meta.bkp new file mode 100644 index 0000000000..c241cc84bc Binary files /dev/null and b/data/.minio.sys/tmp/.trash/99633b28-5c1c-4f9e-93bc-0d113c01e530/xl.meta.bkp differ diff --git a/data/.minio.sys/tmp/.trash/e89e6046-ada6-4f68-b58e-ae79b2b430aa/xl.meta.bkp b/data/.minio.sys/tmp/.trash/e89e6046-ada6-4f68-b58e-ae79b2b430aa/xl.meta.bkp new file mode 100644 index 0000000000..4bf6eba09d Binary files /dev/null and b/data/.minio.sys/tmp/.trash/e89e6046-ada6-4f68-b58e-ae79b2b430aa/xl.meta.bkp differ diff --git a/data/.minio.sys/tmp/17c57519-fb9e-459c-8cd1-b5f08d0b4fe1 b/data/.minio.sys/tmp/17c57519-fb9e-459c-8cd1-b5f08d0b4fe1 new file mode 100644 index 0000000000..e36ee44665 Binary files /dev/null and b/data/.minio.sys/tmp/17c57519-fb9e-459c-8cd1-b5f08d0b4fe1 differ diff --git a/example/linux/installation.md b/example/linux/installation.md new file mode 100644 index 0000000000..997e48b99c --- /dev/null +++ b/example/linux/installation.md @@ -0,0 +1,246 @@ +# Talawa API Installation Guide + +This guide provides step-by-step instructions for setting up the Talawa API service on a Linux system using systemd. + +## Prerequisites + +- **fnm** (Fast Node Manager) +- **Node.js** (`jq -r '.engines.node' package.json`) +- **tsx** (TypeScript execution environment, install globally with `npm install -g tsx`) +- A Linux system with **systemd** +- **Root access** or `sudo` privileges for service installation +- **Dedicated system user** `talawa` for running the service (security best practice) +- **MongoDB** installed and running (required for Talawa API) +- **Redis** installed and running (required for Talawa API) +- Proper file permissions on `/path/to/your/talawa-api` (e.g., /opt/talawa-api or /usr/local/talawa-api) +- For development: + - Ensure `.env` file sets `NODE_ENV=development` + - Run the service manually to verify functionality +- For production: + - Build the app to generate the `dist` folder + - Ensure `.env` file sets `NODE_ENV=production` +- **Log file setup**: + - Ensure a log file exists at `/var/log/talawa-api.log` with appropriate permissions and ownership +- Verify Node.js version in your system matches the version required by `package.json` +- Install `jq` for parsing JSON data (`sudo apt install jq` or equivalent) + +## Steps + +### 1. Create a Dedicated System User + +- Create a user named `talawa` for running the service: + +```bash +sudo adduser --system --no-create-home --group talawa +``` + +- Verify the user creation: + +```bash +id talawa +``` + +### 2. Create the Systemd Service File + +- Create the `talawa-api.service` file in the `/etc/systemd/system/` directory with root privileges +- Check following placeholders: + - `ExecStart` (path to your `Talawa-api.sh` script: `/path/to/your/talawa-api/example/linux/systemd/Talawa-api.sh`) + - `WorkingDirectory` (root directory of your Talawa API project: `/path/to/your/talawa-api`) + - `ReadOnlyPaths` (root directory of your Talawa API project: `/path/to/your/talawa-api`) + - `User, Group` (use the `talawa` user and group created earlier) +- Refer to the example in `/path/to/your/talawa-api/example/linux/systemd/talawa-api.service` for guidance +- Copy `talawa-api.service` then paste it inside `/etc/systemd/system/` +- Make sure `talawa-api.service` is owned by root + +### 3. Set Up the `Talawa-api.sh` Script + +- Edit the script to specify: + - **Project directory** (e.g., `/path/to/your/talawa-api`) + - **Log file path** (e.g., `/var/log/talawa-api.log`) + - Ensure that the development (`src/index.ts`) and production (`dist/index.js`) paths are correctly set + - Make sure `Talawa-api.sh` is executable and owned by user `talawa`. Log file should also be owned by user `talawa` + +### 4. Configure the Environment + +- Ensure the `.env` file exists in the project directory and contains the appropriate configuration +- Add the following environment variables: + - `NODE_ENV=development` or `NODE_ENV=production` + +### 5. Verify Log File and Permissions + +- Create the log file if it does not exist: + +```bash +sudo touch /var/log/talawa-api.log +sudo chown talawa:talawa /var/log/talawa-api.log +sudo chmod 664 /var/log/talawa-api.log +``` + +- Ensure the log file owner matches the service user (e.g., `talawa`) + +### 6. Set Up Log Rotation + +- Create a new logrotate configuration file for Talawa API: + +```bash +sudo nano /etc/logrotate.d/talawa-api +``` + +- Add the following configuration: + +```plaintext +/var/log/talawa-api.log { + su talawa talawa + weekly + rotate 4 + compress + missingok + notifempty + create 664 talawa talawa + # Prevent symlink attacks + nolinkasym + # Delete old versions of log files + delaycompress + # Don't rotate empty log files + notifempty + postrotate + systemctl restart talawa-api.service > /dev/null 2>&1 || true + endscript +} +``` + +- Verify logrotate setup: + +```bash +sudo logrotate -f /etc/logrotate.d/talawa-api +sudo logrotate -v /etc/logrotate.conf +sudo logrotate -d /etc/logrotate.conf +``` + +- -f for forced rotation, -v for verbose rotation, -d for debuging mode rotation. +- To confirm log rotation, check the rotated logs: + +```bash +ls -la /var/log/talawa-api.log* +``` + +### 7. Install Dependencies + +- Install required Node.js version with `fnm`: + +```bash +fnm install +fnm use +``` + +Replace `` with the version specified in `package.json` (`engines.node`) +- Install dependencies: + +```bash +npm install +``` + +- Globally install `tsx` if not already installed: + +```bash +npm install -g tsx +``` + +- Install `jq`: + +```bash +sudo apt install jq +``` + +### 8. Enable and Start the Service + +1. Reload the systemd configuration: + +```bash +sudo systemctl daemon-reload +``` + +2. Verify service security settings: + +```bash +sudo systemd-analyze security talawa-api.service +``` + +3. Enable the service: + +```bash +sudo systemctl enable talawa-api.service +``` + +4. Start the service: + +```bash +sudo systemctl start talawa-api.service +``` + +### 9. Verify the Installation + +- Check the status of the service: + +```bash +sudo systemctl status talawa-api.service +``` + +- View logs in real-time: + +```bash +sudo journalctl -u talawa-api.service -f +``` + +- Check for errors: + +```bash +sudo journalctl -u talawa-api.service -p err +``` + +- Verify the service configuration: + +```bash +sudo systemd-analyze verify talawa-api.service +``` + +- Verify service dependencies: + +```bash +sudo systemctl list-dependencies talawa-api.service +``` + +## Notes + +- Ensure the `Talawa-api.sh` script has executable permissions: + +```bash +chmod +x /path/to/Talawa-api.sh +``` + +- Adjust `LimitNOFILE` and security-related settings in the `talawa-api.service` file as needed for your environment +- For production, ensure the `dist` folder exists by running: + +```bash +npm run build +``` + +- If you encounter any issues, refer to the logs in `/var/log/talawa-api.log` or use `journalctl` +- Don't try to create a global variable to store paths for use in both systemd service and script files. Global variables (like `/path/to/your/talawa-api`) will not work properly as systemd services run in a separate environment. While there are various suggested solutions (using `/etc/environment`, `/etc/default/`, or `Environment` and `EnvironmentFile` directives), these approaches can complicate service execution and are not recommended. +- While systemd supports environment variables through EnvironmentFile and Environment directives, using absolute paths in both the service file and script ensures consistent behavior across different environments and makes debugging easier. + +### Additional Steps for Troubleshooting + +1. Verify Node.js and `tsx` installation: + +```bash +node -v +tsx -v +``` + +2. Ensure MongoDB and Redis are running: + +```bash +sudo systemctl status mongod +sudo systemctl status redis +``` diff --git a/example/linux/systemd/Talawa-api.sh b/example/linux/systemd/Talawa-api.sh new file mode 100755 index 0000000000..b9f21ff454 --- /dev/null +++ b/example/linux/systemd/Talawa-api.sh @@ -0,0 +1,176 @@ +#!/bin/bash +# filepath: /path/to/your/talawa-api/example/linux/systemd/Talawa-api.sh +# Description: Talawa API startup script + +# Don't use environment variables in this script, as when the script will run by systemd, it will not have access to the environment variables of the user. I have tried setting the environment variables in the systemd service file but it didn't work. So, directly use the absolute paths in the script. + +#only Editable part is Project directory path +PROJECT_DIR="/path/to/your/talawa-api" + +#static part +LOG_FILE="/var/log/talawa-api.log" +DEV_PATH="src/index.ts" +PROD_PATH="dist/index.js" + +# Check if the log file exists +if [ ! -f "$LOG_FILE" ]; then + echo "Error: Log file '$LOG_FILE' not found. Exiting." + echo "Please create it first with the correct ownership and permissions, then return." + exit 1 +fi + +# Get the current user +CURRENT_USER=$(whoami) + +# Get the owner of the log file +LOG_FILE_OWNER=$(stat -c '%U' "$LOG_FILE") + +# Check if the current user matches the owner of the log file +if [ "$CURRENT_USER" != "$LOG_FILE_OWNER" ]; then + echo "Error: Current user '$CURRENT_USER' does not match the owner of the log file '$LOG_FILE_OWNER'. Exiting." + echo "Change ownership or permissions and try again." + exit 1 +fi + +# Check if the user has necessary permissions to read and write to the log file +if [ ! -w "$LOG_FILE" ] || [ ! -r "$LOG_FILE" ]; then + echo "Error: User '$CURRENT_USER' does not have sufficient permissions to read or write to the log file '$LOG_FILE'. Exiting." + echo "Change permissions and try again." + exit 1 +fi + +echo "-------------------------------***************------------------------------------" | tee -a "$LOG_FILE" +echo "------------------------------>Talawa-API Logs<-----------------------------------" | tee -a "$LOG_FILE" +echo "------------------------------>Current session date: $(date)" | tee -a "$LOG_FILE" +echo "-------------------------------***************------------------------------------" | tee -a "$LOG_FILE" +echo "Log file '$LOG_FILE' is present and writable by user '$CURRENT_USER'. Proceeding..." | tee -a "$LOG_FILE" + +# Verify the project directory exists +if [ ! -d "$PROJECT_DIR" ]; then + echo "Error: Project directory '$PROJECT_DIR' not found. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi + +# Switch to the project directory +cd "$PROJECT_DIR" || { echo "Error: Failed to change to project directory '$PROJECT_DIR'. Exiting." | tee -a "$LOG_FILE"; exit 1; } + +echo "Changed to project directory '$PROJECT_DIR'. Proceeding..." | tee -a "$LOG_FILE" + +# Check for package.json in the current working directory +if [ ! -f "package.json" ]; then + echo "Error: 'package.json' not found in $(pwd). Exiting." | tee -a "$LOG_FILE" + echo "Please ensure it is present, then return." | tee -a "$LOG_FILE" + exit 1 +fi + +echo "package.json is present in $(pwd). Proceeding..." | tee -a "$LOG_FILE" + +if ! command -v jq >/dev/null 2>&1; then + echo "Error: 'jq' is not installed on this system. Exiting." | tee -a "$LOG_FILE" + echo "It is required to parse the Node.js version from package.json." | tee -a "$LOG_FILE" + echo "Please install 'jq' manually, then return to the script." | tee -a "$LOG_FILE" + exit 1 +fi + +echo "'jq' is present. Proceeding..." | tee -a "$LOG_FILE" + +# Attempt to read the required Node.js version +TARGET_NODE_VERSION=$(jq -r '.engines.node' package.json 2>/dev/null) + +# Continue with your script... +if [ -z "$TARGET_NODE_VERSION" ] || [ "$TARGET_NODE_VERSION" == "null" ]; then + echo "Error: Unable to read 'engines.node' from package.json. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi + +# Remove 'v' prefix if present, e.g. "v20.18.0" -> "20.18.0" +INSTALLED_NODE_VERSION=$(node -v 2>/dev/null | sed 's/^v//') + +echo "Installed Node.js version: $INSTALLED_NODE_VERSION" | tee -a "$LOG_FILE" +echo "Target Node.js version: $TARGET_NODE_VERSION" | tee -a "$LOG_FILE" + +if [ "$INSTALLED_NODE_VERSION" != "$TARGET_NODE_VERSION" ]; then + echo "Error: Node.js version mismatch. Found $INSTALLED_NODE_VERSION, need $TARGET_NODE_VERSION. Exiting." | tee -a "$LOG_FILE" + echo "First install the required Node.js version from package.json in system then proceed further. It should match system Node.js version and Talawa-api Node.js version v$TARGET_NODE_VERSION" | tee -a "$LOG_FILE" + exit 1 +fi + +echo "Node.js version matched. Proceeding..." | tee -a "$LOG_FILE" + +# Check if tsx is installed +if ! command -v tsx >/dev/null 2>&1; then + echo "Error: 'tsx' is not installed on this system. Exiting." | tee -a "$LOG_FILE" + echo "Please install 'tsx' manually, then rerun the script." | tee -a "$LOG_FILE" + exit 1 +fi + +# Define the path to the tsx executable dynamically +TSX_PATH=$(which tsx) + +# Check if the TSX_PATH is valid +if [ ! -x "$TSX_PATH" ]; then + echo "Error: Path for 'tsx' is not found or not executable. Verify it is properly installed. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi + +echo "'tsx' is installed and executable at '$TSX_PATH'. Proceeding..." | tee -a "$LOG_FILE" + +# Define the path to the node executable dynamically +NODE_PATH=$(which node) + +# Check if the NODE_PATH is valid +if [ ! -x "$NODE_PATH" ]; then + echo "Error: Path for 'node' is not found or not executable. Verify it is properly installed. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi + +echo "'node' is installed and executable at '$NODE_PATH'. Proceeding..." | tee -a "$LOG_FILE" + +# Validate paths for development and production +if [ ! -f "$DEV_PATH" ]; then + echo "Error: Development path '$DEV_PATH' not found. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi + +if [ ! -f "$PROD_PATH" ]; then + echo "Error: Production path '$PROD_PATH' not found. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi + +echo "Development and production paths are valid. Proceeding..." | tee -a "$LOG_FILE" + +# Check if .env file is present +if [ ! -f ".env" ]; then + echo "Error: '.env' file not found. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi +echo ".env file found in '$(pwd)' directory. Proceeding..." | tee -a "$LOG_FILE" + +# Load environment variables from .env file securely +NODE_ENV=$(grep '^NODE_ENV=' .env | cut -d '=' -f2) +if [ -n "$NODE_ENV" ]; then + export NODE_ENV +else + echo "Error: NODE_ENV not found in .env file" | tee -a "$LOG_FILE" + exit 1 +fi + +# Check if NODE_ENV is set +if [ -z "$NODE_ENV" ]; then + echo "Error: Property 'NODE_ENV' is not present in the .env file. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi + +echo "Environment variable 'NODE_ENV' is set to '$NODE_ENV'. Proceeding..." | tee -a "$LOG_FILE" + +# Check the value of NODE_ENV and execute the corresponding command +if [ "$NODE_ENV" == "development" ]; then + echo "Starting Talawa API in development mode..." | tee -a "$LOG_FILE" + exec "$TSX_PATH" "$DEV_PATH" +elif [ "$NODE_ENV" == "production" ]; then + echo "Starting Talawa API in production mode..." | tee -a "$LOG_FILE" + exec "$NODE_PATH" "$PROD_PATH" +else + echo "NODE_ENV is not set to a valid value. Please set it to 'development' or 'production'. Exiting." | tee -a "$LOG_FILE" + exit 1 +fi \ No newline at end of file diff --git a/example/linux/systemd/talawa-api.service b/example/linux/systemd/talawa-api.service new file mode 100644 index 0000000000..d11851d52b --- /dev/null +++ b/example/linux/systemd/talawa-api.service @@ -0,0 +1,48 @@ +# Talawa API Systemd Service Configuration +# +# This service file is used to manage the Talawa API service. +# +# README: +# 1. Edit the paths in the `[Editable Configuration]` section to match your setup. +# 2. `Environment=CODEROOT` specifies the root directory of the Talawa API project. +# 3. `ExecStart` should reference the absolute path to the Talawa-api.sh script. +# 4. `WorkingDirectory` must match the root project directory. +# 5. The service runs as the `talawa` user and group for better security. +# 6. The `RuntimeDirectory` creates a directory under `/run` for storing temporary runtime data. +# 7. `LimitNOFILE=15000` ensures the service has sufficient open file descriptors for typical usage patterns. +# 8. Do not modify the `[Static Configuration]` section unless absolutely necessary. +# 9. Use `journalctl` for service logs (`journalctl -u talawa-api.service`). +# 10. After editing, reload systemd with `sudo systemctl daemon-reload`. +# 11. In my case Environment did not worked properly in case if you faced error in readind directory path use absolute path. + +######################################### +# [Editable Configuration] +######################################### +[Unit] +Description=Talawa-API Service + +[Service] +Environment=CODEROOT=/path/to/your/talawa-api +ExecStart=$CODEROOT/example/linux/systemd/Talawa-api.sh +User=talawa +Group=talawa +RuntimeDirectory=talawa-api +LimitNOFILE=15000 + +######################################### +# [Static Configuration] +######################################### +After=network.target +WorkingDirectory=$CODEROOT +Type=simple +Restart=always +RestartSec=5 +StandardOutput=journal+console +StandardError=journal+console +NoNewPrivileges=true +PrivateTmp=true +RestrictAddressFamilies=AF_INET AF_INET6 +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target diff --git a/images/0ebg7HyP8HjIpP97kc9eFimage.png b/images/0ebg7HyP8HjIpP97kc9eFimage.png new file mode 100644 index 0000000000..81413d434d --- /dev/null +++ b/images/0ebg7HyP8HjIpP97kc9eFimage.png @@ -0,0 +1 @@ +media content \ No newline at end of file diff --git a/images/6lFrZPt8zAPumkUQugmU3image.png b/images/6lFrZPt8zAPumkUQugmU3image.png new file mode 100644 index 0000000000..e69de29bb2 diff --git a/images/S_fGEW2OIc4pipoTvX8emimage.png b/images/S_fGEW2OIc4pipoTvX8emimage.png new file mode 100644 index 0000000000..686ec84057 --- /dev/null +++ b/images/S_fGEW2OIc4pipoTvX8emimage.png @@ -0,0 +1 @@ +mf�6��FV�@ \ No newline at end of file diff --git a/images/ij1Fp40yJzM0E4iRFXWGRimage.png b/images/ij1Fp40yJzM0E4iRFXWGRimage.png new file mode 100644 index 0000000000..81413d434d --- /dev/null +++ b/images/ij1Fp40yJzM0E4iRFXWGRimage.png @@ -0,0 +1 @@ +media content \ No newline at end of file diff --git a/images/wc14qUmQDQtFOeSmIhYIgimage.png b/images/wc14qUmQDQtFOeSmIhYIgimage.png new file mode 100644 index 0000000000..81413d434d --- /dev/null +++ b/images/wc14qUmQDQtFOeSmIhYIgimage.png @@ -0,0 +1 @@ +media content \ No newline at end of file diff --git a/schema.graphql b/schema.graphql index 38b099b7ef..e9d2f02241 100644 --- a/schema.graphql +++ b/schema.graphql @@ -163,6 +163,226 @@ enum AgendaItemType { song } +type AgendaFolder { + """ + GraphQL connection to traverse through the agenda folders that have the agenda folder as a parent folder. + """ + childFolders(after: String, before: String, first: Int, last: Int): AgendaFolderChildFoldersConnection + + """Date time at the time the agenda folder was last created.""" + createdAt: DateTime + + """User who created the agenda folder.""" + creator: User + + """Event associated to the agenda folder.""" + event: Event + + """Global identifier of the agenda folder.""" + id: ID! + + """ + Boolean to tell if the agenda folder is meant to be a folder for agenda items or a parent for agenda folders. + """ + isAgendaItemFolder: Boolean + + """ + GraphQL connection to traverse through the agenda item associated to the agenda folder. + """ + items(after: String, before: String, first: Int, last: Int): AgendaFolderItemsConnection + + """Name of the agenda folder.""" + name: String + + """Agenda folder that is a parent folder to the agenda folder.""" + parentFolder: AgendaFolder + + """Date time at the time the agenda folder was last updated.""" + updatedAt: DateTime + + """User who last updated the agenda folder.""" + updater: User +} + +"""""" +type AgendaFolderChildFoldersConnection { + edges: [AgendaFolderChildFoldersConnectionEdge] + pageInfo: PageInfo! +} + +"""""" +type AgendaFolderChildFoldersConnectionEdge { + cursor: String! + node: AgendaFolder +} + +"""""" +type AgendaFolderItemsConnection { + edges: [AgendaFolderItemsConnectionEdge] + pageInfo: PageInfo! +} + +"""""" +type AgendaFolderItemsConnectionEdge { + cursor: String! + node: AgendaItem +} + +type AgendaItem { + """Date time at the time the agenda item was last created.""" + createdAt: DateTime + + """User who created the agenda item.""" + creator: User + + """Custom information about the agenda item.""" + description: String + + """Duration of the agenda item.""" + duration: String + + """Agenda folder associated to the agenda item.""" + event: AgendaFolder + + """Global identifier of the agenda item.""" + id: ID! + + """ + Key of the agenda item if it's type is "song". More information at [this](https://en.wikipedia.org/wiki/Key_(music)) link. + """ + key: String + + """Name of the agenda item.""" + name: String + + """Type of the agenda item.""" + type: AgendaItemType + + """Date time at the time the agenda item was last updated.""" + updatedAt: DateTime + + """User who last updated the agenda item.""" + updater: User +} + +"""""" +enum AgendaItemType { + general + note + scripture + song +} + +type AgendaFolder { + """ + GraphQL connection to traverse through the agenda folders that have the agenda folder as a parent folder. + """ + childFolders(after: String, before: String, first: Int, last: Int): AgendaFolderChildFoldersConnection + + """Date time at the time the agenda folder was last created.""" + createdAt: DateTime + + """User who created the agenda folder.""" + creator: User + + """Event associated to the agenda folder.""" + event: Event + + """Global identifier of the agenda folder.""" + id: ID! + + """ + Boolean to tell if the agenda folder is meant to be a folder for agenda items or a parent for agenda folders. + """ + isAgendaItemFolder: Boolean + + """ + GraphQL connection to traverse through the agenda item associated to the agenda folder. + """ + items(after: String, before: String, first: Int, last: Int): AgendaFolderItemsConnection + + """Name of the agenda folder.""" + name: String + + """Agenda folder that is a parent folder to the agenda folder.""" + parentFolder: AgendaFolder + + """Date time at the time the agenda folder was last updated.""" + updatedAt: DateTime + + """User who last updated the agenda folder.""" + updater: User +} + +"""""" +type AgendaFolderChildFoldersConnection { + edges: [AgendaFolderChildFoldersConnectionEdge] + pageInfo: PageInfo! +} + +"""""" +type AgendaFolderChildFoldersConnectionEdge { + cursor: String! + node: AgendaFolder +} + +"""""" +type AgendaFolderItemsConnection { + edges: [AgendaFolderItemsConnectionEdge] + pageInfo: PageInfo! +} + +"""""" +type AgendaFolderItemsConnectionEdge { + cursor: String! + node: AgendaItem +} + +type AgendaItem { + """Date time at the time the agenda item was last created.""" + createdAt: DateTime + + """User who created the agenda item.""" + creator: User + + """Custom information about the agenda item.""" + description: String + + """Duration of the agenda item.""" + duration: String + + """Agenda folder associated to the agenda item.""" + event: AgendaFolder + + """Global identifier of the agenda item.""" + id: ID! + + """ + Key of the agenda item if it's type is "song". More information at [this](https://en.wikipedia.org/wiki/Key_(music)) link. + """ + key: String + + """Name of the agenda item.""" + name: String + + """Type of the agenda item.""" + type: AgendaItemType + + """Date time at the time the agenda item was last updated.""" + updatedAt: DateTime + + """User who last updated the agenda item.""" + updater: User +} + +"""""" +enum AgendaItemType { + general + note + scripture + song +} + """""" type AuthenticationPayload { """ @@ -274,6 +494,98 @@ type ChatMessagesConnectionEdge { node: ChatMessage } +type Chat { + """URI to the avatar of the chat.""" + avatarURI: String + + """Date time at the time the chat was created.""" + createdAt: DateTime + + """User who created the chat.""" + creator: User + + """Custom information about the chat.""" + description: String + + """Global identifier of the chat.""" + id: ID! + + """ + GraphQL connection to traverse through the users that are members of the chat. + """ + members(after: String, before: String, first: Int, last: Int): ChatMembersConnection + + """ + GraphQL connection to traverse through the chat messages that are associated to the chat. + """ + messages(after: String, before: String, first: Int, last: Int): ChatMessagesConnection + + """Name of the chat.""" + name: String + + """Organization which the chat is associated to.""" + organization: Organization + + """Date time at the time the chat was last updated.""" + updatedAt: DateTime + + """User who last updated the chat.""" + updater: User +} + +"""""" +type ChatMembersConnection { + edges: [ChatMembersConnectionEdge] + pageInfo: PageInfo! +} + +"""""" +type ChatMembersConnectionEdge { + cursor: String! + node: User +} + +"""""" +enum ChatMembershipRole { + administrator + regular +} + +type ChatMessage { + """Body of the chat message.""" + body: String + + """Chat which the chat message belongs to.""" + chat: Chat + + """Date time at the time the chat message was created.""" + createdAt: DateTime + + """User who created the chat message.""" + creator: User + + """Global identifier of the chat message.""" + id: ID! + + """Parent chat message of the chat message.""" + parentChatMessage: ChatMessage + + """Date time at the time the chat message was last updated.""" + updatedAt: DateTime +} + +"""""" +type ChatMessagesConnection { + edges: [ChatMessagesConnectionEdge] + pageInfo: PageInfo! +} + +"""""" +type ChatMessagesConnectionEdge { + cursor: String! + node: ChatMessage +} + type Comment { """Body of the comment.""" body: String diff --git a/videos/lAAm87jrFUm8M_z9_zbD4video.mp4 b/videos/lAAm87jrFUm8M_z9_zbD4video.mp4 new file mode 100644 index 0000000000..81413d434d --- /dev/null +++ b/videos/lAAm87jrFUm8M_z9_zbD4video.mp4 @@ -0,0 +1 @@ +media content \ No newline at end of file diff --git a/videos/t8_tJ0AXt0nprfOQHQowjvideo.mp4 b/videos/t8_tJ0AXt0nprfOQHQowjvideo.mp4 new file mode 100644 index 0000000000..9709467a1b --- /dev/null +++ b/videos/t8_tJ0AXt0nprfOQHQowjvideo.mp4 @@ -0,0 +1 @@ +�f�6��FV�@ \ No newline at end of file