diff --git a/GITHUB_SETUP.md b/GITHUB_SETUP.md index f93a5cf..83f2ad1 100644 --- a/GITHUB_SETUP.md +++ b/GITHUB_SETUP.md @@ -5,12 +5,14 @@ Add these secrets to your GitHub repository (Settings > Secrets and variables > Actions): ### AWS Credentials + ``` AWS_ACCESS_KEY_ID=your-aws-access-key AWS_SECRET_ACCESS_KEY=your-aws-secret-key ``` ### JWT Configuration (CRITICAL - Generate secure random strings) + ``` JWT_SECRET=your-super-secure-jwt-secret-key-here JWT_SECRET_REFRESH=your-super-secure-refresh-secret-key-here @@ -18,12 +20,14 @@ SECRET_KEY=your-general-encryption-secret-key-here ``` ### Admin Configuration + ``` SUPER_ADMIN_EMAIL=admin@syncrow.ae SUPER_ADMIN_PASSWORD=YourSecureAdminPassword123! ``` ### Tuya IoT Configuration + ``` TUYA_ACCESS_ID=your-tuya-access-id TUYA_ACCESS_KEY=your-tuya-access-key @@ -31,6 +35,7 @@ TRUN_ON_TUYA_SOCKET=true-or-false ``` ### Firebase Configuration + ``` FIREBASE_API_KEY=your-firebase-api-key FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com @@ -43,18 +48,21 @@ FIREBASE_DATABASE_URL=https://your-project.firebaseio.com ``` ### Google OAuth + ``` GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret ``` ### OneSignal Push Notifications + ``` ONESIGNAL_APP_ID=your-onesignal-app-id ONESIGNAL_API_KEY=your-onesignal-api-key ``` ### Email Configuration (SMTP) + ``` SMTP_HOST=your-smtp-host SMTP_USER=your-smtp-username @@ -62,6 +70,7 @@ SMTP_PASSWORD=your-smtp-password ``` ### Mailtrap Configuration + ``` MAILTRAP_API_TOKEN=your-mailtrap-api-token MAILTRAP_ENABLE_TEMPLATE_UUID=template-uuid @@ -72,6 +81,7 @@ MAILTRAP_EDIT_USER_TEMPLATE_UUID=template-uuid ``` ### Optional Services (leave empty if not used) + ``` AZURE_REDIS_CONNECTIONSTRING=your-redis-connection-string DOPPLER_PROJECT=your-doppler-project @@ -101,7 +111,7 @@ DOCKER_REGISTRY_SERVER_PASSWORD=your-registry-password 4. **Test Deployment** - Push to master/main branch - Check GitHub Actions tab for deployment status - - Verify API is accessible at https://api.syncrow.me + - Verify API is accessible at https://api.syncos.syncrow.ae ## Security Notes diff --git a/README.md b/README.md index a9c7753..9ab1f26 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ # Backend ## Overview + This is the backend for an IoT application built using NestJS. It interfaces with the Tuya IoT cloud platform to manage homes, rooms, devices, ...etc. -This is the backend APIs project, developed with NestJS for Syncrow IOT Project. +This is the backend APIs project, developed with NestJS for Syncrow IOT Project. ## Database Model + The database uses PostgreSQL and TypeORM. Below is an entity relationship diagram: The main entities are: User - Stores user account information -Home - Represents a home/space -Room - Represents a room/sub-space +Home - Represents a home/space +Room - Represents a room/sub-space Device - Represents a connected device Product - Stores metadata about device products Other Entities - sessions, OTPs, etc. @@ -19,10 +21,11 @@ Other Entities - sessions, OTPs, etc. The entities have a one-to-many relationship - a user has multiple homes, a home has multiple rooms, and a room has multiple devices. ## Architecture + The application is deployed on Azure App Service using Docker containers. There are separate deployment slots for development, staging, and production environments. - ## Installation + First, ensure that you have Node.js `v20.11` or newer (LTS ONLY) installed on your system. To install the project dependencies, run the following command in the project root directory: @@ -61,8 +64,8 @@ $ npm run test:cov ![Syncrow ERD Digram](https://github.com/SyncrowIOT/backend/assets/83524184/94273a2b-625c-4a34-9cd4-fb14415ce884) - ## Architecture + +----------------------------------+ | | | Applications | @@ -120,8 +123,8 @@ $ npm run test:cov • After code changes: build Docker image, push to ECR, force ECS deployment • Database seeding happens automatically on first deployment with DB_SYNC=true • Admin credentials: admin@syncrow.ae / YourSecureAdminPassword123! -• Production API: https://api.syncrow.me -• Health check: https://api.syncrow.me/health +• Production API: https://api.syncos.syncrow.ae +• Health check: https://api.syncos.syncrow.ae/health ## GitHub Actions Deployment diff --git a/cdk.context.json b/cdk.context.json index 13bd4e7..9f16f8b 100644 --- a/cdk.context.json +++ b/cdk.context.json @@ -21,5 +21,9 @@ "hosted-zone:account=482311766496:domainName=syncrow.me:region=me-central-1": { "Id": "/hostedzone/Z02085662NLJECF4DGJV3", "Name": "syncrow.me." + }, + "hosted-zone:account=482311766496:domainName=syncrow.ae:region=me-central-1": { + "Id": "/hostedzone/Z01153152LRHQTA1370P4", + "Name": "syncrow.ae." } } diff --git a/infrastructure/app.ts b/infrastructure/app.ts index 0231816..b346b3c 100644 --- a/infrastructure/app.ts +++ b/infrastructure/app.ts @@ -12,5 +12,5 @@ new BackendStack(app, 'SyncrowBackendStack', { }, databaseName: 'postgres', certificateArn: - 'arn:aws:acm:me-central-1:482311766496:certificate/bea1e2ae-84a1-414e-8dbf-4599397e7ed0', + 'arn:aws:acm:me-central-1:482311766496:certificate/423b343e-402b-4978-89bd-cda25f7a8873', }); diff --git a/infrastructure/stack.ts b/infrastructure/stack.ts index 4342a5d..a8ea560 100644 --- a/infrastructure/stack.ts +++ b/infrastructure/stack.ts @@ -168,7 +168,7 @@ export class BackendStack extends cdk.Stack { props.certificateArn, ) : new acm.Certificate(this, 'ApiCertificate', { - domainName: 'api.syncrow.me', + domainName: 'api.syncos.syncrow.ae', validation: acm.CertificateValidation.fromDns(), }); @@ -182,9 +182,9 @@ export class BackendStack extends cdk.Stack { memoryLimitMiB: 1024, cpu: 512, desiredCount: 2, - domainName: 'api.syncrow.me', + domainName: 'api.syncos.syncrow.ae', domainZone: route53.HostedZone.fromLookup(this, 'SyncrowZone', { - domainName: 'syncrow.me', + domainName: 'syncrow.ae', }), certificate: apiCertificate, protocol: elbv2.ApplicationProtocol.HTTPS, @@ -356,7 +356,7 @@ export class BackendStack extends cdk.Stack { // Grant ECS task access to RDS credentials dbSecret.grantRead(fargateService.taskDefinition.taskRole); - this.apiUrl = 'https://api.syncrow.me'; + this.apiUrl = 'https://api.syncos.syncrow.ae'; this.databaseEndpoint = dbCluster.clusterEndpoint.hostname; // Outputs diff --git a/package-lock.json b/package-lock.json index ec4bbcd..3cff842 100644 --- a/package-lock.json +++ b/package-lock.json @@ -852,7 +852,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -865,7 +865,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -3035,28 +3035,28 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tuya/tuya-connector-nodejs": { @@ -3853,7 +3853,7 @@ "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -4040,7 +4040,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/argon2": { @@ -5910,7 +5910,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cross-spawn": { @@ -6194,7 +6194,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -10286,7 +10286,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/makeerror": { @@ -13405,7 +13405,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -13816,7 +13816,7 @@ "version": "5.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -13962,7 +13962,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -14540,7 +14540,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6"