From 24b59d1bbd1f1f48da72f3275338350c584f72e6 Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:29:40 +0300 Subject: [PATCH 1/7] fix deploy staging --- .github/workflows/main_syncrow(staging).yml | 76 ++++++++++----------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/.github/workflows/main_syncrow(staging).yml b/.github/workflows/main_syncrow(staging).yml index 952632a..c926795 100644 --- a/.github/workflows/main_syncrow(staging).yml +++ b/.github/workflows/main_syncrow(staging).yml @@ -1,4 +1,7 @@ -name: Backend deployment to Azure App Service +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy container app to Azure Web App - syncrow(test) on: push: @@ -6,50 +9,43 @@ on: - main workflow_dispatch: -env: - AZURE_WEB_APP_NAME: 'syncrow' - AZURE_WEB_APP_SLOT_NAME: 'staging' - ACR_REGISTRY: 'syncrow.azurecr.io' - IMAGE_NAME: 'backend' - IMAGE_TAG: 'latest' - jobs: - build_and_deploy: - runs-on: ubuntu-latest + build: + runs-on: 'ubuntu-latest' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: '20' + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 - - name: Install dependencies and build project - run: | - npm install - npm run build + - name: Log in to registry + uses: docker/login-action@v2 + with: + registry: https://syncrow.azurecr.io/ + username: ${{ secrets.AzureAppService_ContainerUsername_e7578d2a094946609a4506f293c7c645 }} + password: ${{ secrets.AzureAppService_ContainerPassword_3cfcef3755ed46eda766dfc7059dcf5e }} - - name: Log in to Azure - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Build and push container image to registry + uses: docker/build-push-action@v3 + with: + push: true + tags: syncrow.azurecr.io/${{ secrets.AzureAppService_ContainerUsername_e7578d2a094946609a4506f293c7c645 }}/backend:${{ github.sha }} + file: ./Dockerfile - - name: Log in to Azure Container Registry - run: az acr login --name ${{ env.ACR_REGISTRY }} + deploy: + runs-on: ubuntu-latest + needs: build + environment: + name: 'test' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - - name: List build output - run: ls -R dist/ - - - name: Build and push Docker image - run: | - docker build . -t ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} - docker push ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} - - - name: Set Web App with Docker container - run: | - az webapp config container set \ - --name ${{ env.AZURE_WEB_APP_NAME }} \ - --resource-group backend \ - --docker-custom-image-name ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} \ - --docker-registry-server-url https://${{ env.ACR_REGISTRY }} + steps: + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v2 + with: + app-name: 'syncrow' + slot-name: 'main' + publish-profile: ${{ secrets.AzureAppService_PublishProfile_cfa029d9d3a84172a06cfe47c05c18ca }} + images: 'syncrow.azurecr.io/${{ secrets.AzureAppService_ContainerUsername_e7578d2a094946609a4506f293c7c645 }}/backend:${{ github.sha }}' \ No newline at end of file From e333a400198e4a308138f0eed90293817a42f11a Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:34:23 +0300 Subject: [PATCH 2/7] Refactor GitHub Actions workflow for backend deployment to Azure App Service --- .github/workflows/main_syncrow(staging).yml | 84 +++++++++++---------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/.github/workflows/main_syncrow(staging).yml b/.github/workflows/main_syncrow(staging).yml index c926795..952632a 100644 --- a/.github/workflows/main_syncrow(staging).yml +++ b/.github/workflows/main_syncrow(staging).yml @@ -1,7 +1,4 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy container app to Azure Web App - syncrow(test) +name: Backend deployment to Azure App Service on: push: @@ -9,43 +6,50 @@ on: - main workflow_dispatch: +env: + AZURE_WEB_APP_NAME: 'syncrow' + AZURE_WEB_APP_SLOT_NAME: 'staging' + ACR_REGISTRY: 'syncrow.azurecr.io' + IMAGE_NAME: 'backend' + IMAGE_TAG: 'latest' + jobs: - build: - runs-on: 'ubuntu-latest' - - steps: - - uses: actions/checkout@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Log in to registry - uses: docker/login-action@v2 - with: - registry: https://syncrow.azurecr.io/ - username: ${{ secrets.AzureAppService_ContainerUsername_e7578d2a094946609a4506f293c7c645 }} - password: ${{ secrets.AzureAppService_ContainerPassword_3cfcef3755ed46eda766dfc7059dcf5e }} - - - name: Build and push container image to registry - uses: docker/build-push-action@v3 - with: - push: true - tags: syncrow.azurecr.io/${{ secrets.AzureAppService_ContainerUsername_e7578d2a094946609a4506f293c7c645 }}/backend:${{ github.sha }} - file: ./Dockerfile - - deploy: + build_and_deploy: runs-on: ubuntu-latest - needs: build - environment: - name: 'test' - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} steps: - - name: Deploy to Azure Web App - id: deploy-to-webapp - uses: azure/webapps-deploy@v2 - with: - app-name: 'syncrow' - slot-name: 'main' - publish-profile: ${{ secrets.AzureAppService_PublishProfile_cfa029d9d3a84172a06cfe47c05c18ca }} - images: 'syncrow.azurecr.io/${{ secrets.AzureAppService_ContainerUsername_e7578d2a094946609a4506f293c7c645 }}/backend:${{ github.sha }}' \ No newline at end of file + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Install dependencies and build project + run: | + npm install + npm run build + + - name: Log in to Azure + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Log in to Azure Container Registry + run: az acr login --name ${{ env.ACR_REGISTRY }} + + - name: List build output + run: ls -R dist/ + + - name: Build and push Docker image + run: | + docker build . -t ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} + docker push ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} + + - name: Set Web App with Docker container + run: | + az webapp config container set \ + --name ${{ env.AZURE_WEB_APP_NAME }} \ + --resource-group backend \ + --docker-custom-image-name ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} \ + --docker-registry-server-url https://${{ env.ACR_REGISTRY }} From 5500910391421c0df962b438f14780b747d04439 Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:48:09 +0300 Subject: [PATCH 3/7] Add or update the App Service deployment workflow configuration from Azure Portal. --- .github/workflows/main_syncrow(staging).yml | 76 ++++++++++----------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/.github/workflows/main_syncrow(staging).yml b/.github/workflows/main_syncrow(staging).yml index 952632a..0d29d1b 100644 --- a/.github/workflows/main_syncrow(staging).yml +++ b/.github/workflows/main_syncrow(staging).yml @@ -1,4 +1,7 @@ -name: Backend deployment to Azure App Service +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy container app to Azure Web App - syncrow(staging) on: push: @@ -6,50 +9,43 @@ on: - main workflow_dispatch: -env: - AZURE_WEB_APP_NAME: 'syncrow' - AZURE_WEB_APP_SLOT_NAME: 'staging' - ACR_REGISTRY: 'syncrow.azurecr.io' - IMAGE_NAME: 'backend' - IMAGE_TAG: 'latest' - jobs: - build_and_deploy: - runs-on: ubuntu-latest + build: + runs-on: 'ubuntu-latest' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: '20' + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 - - name: Install dependencies and build project - run: | - npm install - npm run build + - name: Log in to registry + uses: docker/login-action@v2 + with: + registry: https://syncrow.azurecr.io/ + username: ${{ secrets.AzureAppService_ContainerUsername_47395803300340b49931ea82f6d80be3 }} + password: ${{ secrets.AzureAppService_ContainerPassword_e7b0ff54f54d44cba04a970a22384848 }} - - name: Log in to Azure - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} + - name: Build and push container image to registry + uses: docker/build-push-action@v3 + with: + push: true + tags: syncrow.azurecr.io/${{ secrets.AzureAppService_ContainerUsername_47395803300340b49931ea82f6d80be3 }}/syncrow/backend:${{ github.sha }} + file: ./Dockerfile - - name: Log in to Azure Container Registry - run: az acr login --name ${{ env.ACR_REGISTRY }} + deploy: + runs-on: ubuntu-latest + needs: build + environment: + name: 'staging' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - - name: List build output - run: ls -R dist/ - - - name: Build and push Docker image - run: | - docker build . -t ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} - docker push ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} - - - name: Set Web App with Docker container - run: | - az webapp config container set \ - --name ${{ env.AZURE_WEB_APP_NAME }} \ - --resource-group backend \ - --docker-custom-image-name ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} \ - --docker-registry-server-url https://${{ env.ACR_REGISTRY }} + steps: + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v2 + with: + app-name: 'syncrow' + slot-name: 'staging' + publish-profile: ${{ secrets.AzureAppService_PublishProfile_44f7766441ec4796b74789e9761ef589 }} + images: 'syncrow.azurecr.io/${{ secrets.AzureAppService_ContainerUsername_47395803300340b49931ea82f6d80be3 }}/syncrow/backend:${{ github.sha }}' \ No newline at end of file From 2253be74d0f181be3c706cb282cf6852b69f0105 Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:57:56 +0300 Subject: [PATCH 4/7] remove defaultProfilePicture --- libs/common/src/modules/user/entities/user.entity.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/common/src/modules/user/entities/user.entity.ts b/libs/common/src/modules/user/entities/user.entity.ts index 5b754e8..bab2420 100644 --- a/libs/common/src/modules/user/entities/user.entity.ts +++ b/libs/common/src/modules/user/entities/user.entity.ts @@ -7,7 +7,6 @@ import { UserRoleEntity } from '../../user-role/entities'; import { DeviceNotificationEntity } from '../../device-notification/entities'; import { UserNotificationEntity } from '../../user-notification/entities'; import { DeviceEntity } from '../../device/entities'; -import { defaultProfilePicture } from '@app/common/constants/default.profile.picture'; import { RegionEntity } from '../../region/entities'; import { TimeZoneEntity } from '../../timezone/entities'; @@ -23,7 +22,7 @@ export class UserEntity extends AbstractEntity { @Column({ nullable: true, type: 'text', - default: defaultProfilePicture, + default: '', }) public profilePicture: string; From c2a6260e25c198842ddee220feed08b8176a6cf6 Mon Sep 17 00:00:00 2001 From: faris Aljohari <83524184+farisaljohari@users.noreply.github.com> Date: Tue, 6 Aug 2024 15:04:19 +0300 Subject: [PATCH 5/7] Add default profile picture to UserEntity --- libs/common/src/modules/user/entities/user.entity.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/common/src/modules/user/entities/user.entity.ts b/libs/common/src/modules/user/entities/user.entity.ts index bab2420..5b754e8 100644 --- a/libs/common/src/modules/user/entities/user.entity.ts +++ b/libs/common/src/modules/user/entities/user.entity.ts @@ -7,6 +7,7 @@ import { UserRoleEntity } from '../../user-role/entities'; import { DeviceNotificationEntity } from '../../device-notification/entities'; import { UserNotificationEntity } from '../../user-notification/entities'; import { DeviceEntity } from '../../device/entities'; +import { defaultProfilePicture } from '@app/common/constants/default.profile.picture'; import { RegionEntity } from '../../region/entities'; import { TimeZoneEntity } from '../../timezone/entities'; @@ -22,7 +23,7 @@ export class UserEntity extends AbstractEntity { @Column({ nullable: true, type: 'text', - default: '', + default: defaultProfilePicture, }) public profilePicture: string; From 427a57501f29d0a519f5412f200456c693670bca Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Sun, 16 Feb 2025 23:26:20 +0400 Subject: [PATCH 6/7] Moved get visitor password and get device for visitor password --- libs/common/src/constants/controller-route.ts | 11 +++++ src/automation/automation.module.ts | 2 + .../controllers/device-project.controller.ts | 29 +++++++++++ src/device/controllers/device.controller.ts | 11 ----- src/device/device.module.ts | 5 +- src/device/dtos/index.ts | 1 + src/device/dtos/project.param.dto.ts | 11 +++++ src/device/services/device.service.ts | 22 ++++++++- src/door-lock/door.lock.module.ts | 2 + src/scene/scene.module.ts | 2 + src/vistor-password/controllers/index.ts | 1 + .../project-visitor-password.controller.ts | 48 +++++++++++++++++++ .../visitor-password.controller.ts | 29 ----------- src/vistor-password/dtos/index.ts | 1 + src/vistor-password/dtos/project.param.dto.ts | 11 +++++ .../services/visitor-password.service.ts | 39 ++++++++++++++- .../visitor-password.module.ts | 5 +- 17 files changed, 185 insertions(+), 45 deletions(-) create mode 100644 src/device/controllers/device-project.controller.ts create mode 100644 src/device/dtos/project.param.dto.ts create mode 100644 src/vistor-password/controllers/project-visitor-password.controller.ts create mode 100644 src/vistor-password/dtos/project.param.dto.ts diff --git a/libs/common/src/constants/controller-route.ts b/libs/common/src/constants/controller-route.ts index 4cee3fe..6478657 100644 --- a/libs/common/src/constants/controller-route.ts +++ b/libs/common/src/constants/controller-route.ts @@ -540,6 +540,15 @@ export class ControllerRoute { }; }; + static DEVICE_PROJECT = class { + public static readonly ROUTE = '/projects/:projectUuid/devices'; + static ACTIONS = class { + public static readonly GET_ALL_DEVICES_SUMMARY = 'Get all devices'; + public static readonly GET_ALL_DEVICES_DESCRIPTION = + 'This endpoint retrieves all devices in the system.'; + }; + }; + static DEVICE_PERMISSION = class { public static readonly ROUTE = 'device-permission'; @@ -680,6 +689,8 @@ export class ControllerRoute { }; static VISITOR_PASSWORD = class { public static readonly ROUTE = 'visitor-password'; + public static readonly PROJECT_ROUTE = + '/projects/:projectUuid/visitor-password'; static ACTIONS = class { public static readonly ADD_ONLINE_TEMP_PASSWORD_MULTIPLE_TIME_SUMMARY = diff --git a/src/automation/automation.module.ts b/src/automation/automation.module.ts index 810c8ec..1230238 100644 --- a/src/automation/automation.module.ts +++ b/src/automation/automation.module.ts @@ -16,6 +16,7 @@ import { } from '@app/common/modules/scene/repositories'; import { SceneDeviceRepository } from '@app/common/modules/scene-device/repositories'; import { AutomationRepository } from '@app/common/modules/automation/repositories'; +import { ProjectRepository } from '@app/common/modules/project/repositiories/project.repository'; @Module({ imports: [ConfigModule, SpaceRepositoryModule, DeviceStatusFirebaseModule], @@ -32,6 +33,7 @@ import { AutomationRepository } from '@app/common/modules/automation/repositorie SceneRepository, SceneDeviceRepository, AutomationRepository, + ProjectRepository, ], exports: [AutomationService], }) diff --git a/src/device/controllers/device-project.controller.ts b/src/device/controllers/device-project.controller.ts new file mode 100644 index 0000000..efdb6ca --- /dev/null +++ b/src/device/controllers/device-project.controller.ts @@ -0,0 +1,29 @@ +import { DeviceService } from '../services/device.service'; +import { Controller, Get, Param, UseGuards } from '@nestjs/common'; +import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger'; +import { EnableDisableStatusEnum } from '@app/common/constants/days.enum'; +import { ControllerRoute } from '@app/common/constants/controller-route'; +import { PermissionsGuard } from 'src/guards/permissions.guard'; +import { Permissions } from 'src/decorators/permissions.decorator'; +import { ProjectParam } from '../dtos'; + +@ApiTags('Device Module') +@Controller({ + version: EnableDisableStatusEnum.ENABLED, + path: ControllerRoute.DEVICE_PROJECT.ROUTE, +}) +export class DeviceProjectController { + constructor(private readonly deviceService: DeviceService) {} + + @ApiBearerAuth() + @UseGuards(PermissionsGuard) + @Permissions('DEVICE_VIEW') + @Get() + @ApiOperation({ + summary: ControllerRoute.DEVICE.ACTIONS.GET_ALL_DEVICES_SUMMARY, + description: ControllerRoute.DEVICE.ACTIONS.GET_ALL_DEVICES_DESCRIPTION, + }) + async getAllDevices(@Param() param: ProjectParam) { + return await this.deviceService.getAllDevices(param); + } +} diff --git a/src/device/controllers/device.controller.ts b/src/device/controllers/device.controller.ts index 1ec8c6c..7bd9efd 100644 --- a/src/device/controllers/device.controller.ts +++ b/src/device/controllers/device.controller.ts @@ -224,17 +224,6 @@ export class DeviceController { async getDevicesInGateway(@Param('gatewayUuid') gatewayUuid: string) { return await this.deviceService.getDevicesInGateway(gatewayUuid); } - @ApiBearerAuth() - @UseGuards(PermissionsGuard) - @Permissions('DEVICE_VIEW') - @Get() - @ApiOperation({ - summary: ControllerRoute.DEVICE.ACTIONS.GET_ALL_DEVICES_SUMMARY, - description: ControllerRoute.DEVICE.ACTIONS.GET_ALL_DEVICES_DESCRIPTION, - }) - async getAllDevices() { - return await this.deviceService.getAllDevices(); - } @ApiBearerAuth() @UseGuards(PermissionsGuard) diff --git a/src/device/device.module.ts b/src/device/device.module.ts index 2a372cc..fdd3350 100644 --- a/src/device/device.module.ts +++ b/src/device/device.module.ts @@ -20,6 +20,8 @@ import { } from '@app/common/modules/scene/repositories'; import { SceneDeviceRepository } from '@app/common/modules/scene-device/repositories'; import { AutomationRepository } from '@app/common/modules/automation/repositories'; +import { ProjectRepository } from '@app/common/modules/project/repositiories'; +import { DeviceProjectController } from './controllers/device-project.controller'; @Module({ imports: [ ConfigModule, @@ -28,13 +30,14 @@ import { AutomationRepository } from '@app/common/modules/automation/repositorie DeviceRepositoryModule, DeviceStatusFirebaseModule, ], - controllers: [DeviceController], + controllers: [DeviceController, DeviceProjectController], providers: [ DeviceService, ProductRepository, DeviceUserPermissionRepository, PermissionTypeRepository, SpaceRepository, + ProjectRepository, DeviceRepository, UserRepository, TuyaService, diff --git a/src/device/dtos/index.ts b/src/device/dtos/index.ts index 1a0b6b3..2c6588d 100644 --- a/src/device/dtos/index.ts +++ b/src/device/dtos/index.ts @@ -1,3 +1,4 @@ export * from './add.device.dto'; export * from './control.device.dto'; export * from './get.device.dto'; +export * from './project.param.dto'; diff --git a/src/device/dtos/project.param.dto.ts b/src/device/dtos/project.param.dto.ts new file mode 100644 index 0000000..8bb2929 --- /dev/null +++ b/src/device/dtos/project.param.dto.ts @@ -0,0 +1,11 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsUUID } from 'class-validator'; + +export class ProjectParam { + @ApiProperty({ + description: 'UUID of the project this community belongs to', + example: 'd290f1ee-6c54-4b01-90e6-d701748f0851', + }) + @IsUUID() + projectUuid: string; +} diff --git a/src/device/services/device.service.ts b/src/device/services/device.service.ts index 45cdafd..615eb68 100644 --- a/src/device/services/device.service.ts +++ b/src/device/services/device.service.ts @@ -60,6 +60,8 @@ import { BaseResponseDto } from '@app/common/dto/base.response.dto'; import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; import { DeleteSceneFromSceneDeviceDto } from '../dtos/delete.device.dto'; import { DeviceEntity } from '@app/common/modules/device/entities'; +import { ProjectRepository } from '@app/common/modules/project/repositiories'; +import { ProjectParam } from '../dtos'; @Injectable() export class DeviceService { @@ -74,6 +76,7 @@ export class DeviceService { @Inject(forwardRef(() => SceneService)) private readonly sceneService: SceneService, private readonly tuyaService: TuyaService, + private readonly projectRepository: ProjectRepository, ) { const accessKey = this.configService.get('auth-config.ACCESS_KEY'); const secretKey = this.configService.get('auth-config.SECRET_KEY'); @@ -950,8 +953,12 @@ export class DeviceService { ); } } - async getAllDevices(): Promise { + async getAllDevices( + param: ProjectParam, + ): Promise { try { + await this.validateProject(param.projectUuid); + const devices = await this.deviceRepository.find({ where: { isActive: true }, relations: [ @@ -1490,4 +1497,17 @@ export class DeviceService { ); } } + + private async validateProject(uuid: string) { + const project = await this.projectRepository.findOne({ + where: { uuid }, + }); + if (!project) { + throw new HttpException( + `A project with the uuid '${uuid}' doesn't exists.`, + HttpStatus.BAD_REQUEST, + ); + } + return project; + } } diff --git a/src/door-lock/door.lock.module.ts b/src/door-lock/door.lock.module.ts index 3cf563b..2e00893 100644 --- a/src/door-lock/door.lock.module.ts +++ b/src/door-lock/door.lock.module.ts @@ -19,6 +19,7 @@ import { } from '@app/common/modules/scene/repositories'; import { SceneDeviceRepository } from '@app/common/modules/scene-device/repositories'; import { AutomationRepository } from '@app/common/modules/automation/repositories'; +import { ProjectRepository } from '@app/common/modules/project/repositiories'; @Module({ imports: [ConfigModule, DeviceRepositoryModule], controllers: [DoorLockController], @@ -32,6 +33,7 @@ import { AutomationRepository } from '@app/common/modules/automation/repositorie DeviceStatusFirebaseService, SpaceRepository, DeviceStatusLogRepository, + ProjectRepository, TuyaService, SceneService, SceneIconRepository, diff --git a/src/scene/scene.module.ts b/src/scene/scene.module.ts index a6a1435..0fe961b 100644 --- a/src/scene/scene.module.ts +++ b/src/scene/scene.module.ts @@ -15,6 +15,7 @@ import { import { TuyaService } from '@app/common/integrations/tuya/services/tuya.service'; import { SceneDeviceRepository } from '@app/common/modules/scene-device/repositories'; import { AutomationRepository } from '@app/common/modules/automation/repositories'; +import { ProjectRepository } from '@app/common/modules/project/repositiories'; @Module({ imports: [ConfigModule, SpaceRepositoryModule, DeviceStatusFirebaseModule], @@ -28,6 +29,7 @@ import { AutomationRepository } from '@app/common/modules/automation/repositorie ProductRepository, SceneIconRepository, SceneRepository, + ProjectRepository, SceneDeviceRepository, AutomationRepository, ], diff --git a/src/vistor-password/controllers/index.ts b/src/vistor-password/controllers/index.ts index ca4b986..b579b2d 100644 --- a/src/vistor-password/controllers/index.ts +++ b/src/vistor-password/controllers/index.ts @@ -1 +1,2 @@ export * from './visitor-password.controller'; +export * from './project-visitor-password.controller'; \ No newline at end of file diff --git a/src/vistor-password/controllers/project-visitor-password.controller.ts b/src/vistor-password/controllers/project-visitor-password.controller.ts new file mode 100644 index 0000000..f72b5c9 --- /dev/null +++ b/src/vistor-password/controllers/project-visitor-password.controller.ts @@ -0,0 +1,48 @@ +import { VisitorPasswordService } from '../services/visitor-password.service'; +import { Controller, UseGuards, Get, Param } from '@nestjs/common'; +import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger'; +import { Permissions } from 'src/decorators/permissions.decorator'; + +import { EnableDisableStatusEnum } from '@app/common/constants/days.enum'; +import { ControllerRoute } from '@app/common/constants/controller-route'; +import { ProjectParam } from 'src/community/dtos'; +import { PermissionsGuard } from 'src/guards/permissions.guard'; + +@ApiTags('Visitor Password Module') +@Controller({ + version: EnableDisableStatusEnum.ENABLED, + path: ControllerRoute.VISITOR_PASSWORD.PROJECT_ROUTE, +}) +export class VisitorPasswordProjectController { + constructor( + private readonly visitorPasswordService: VisitorPasswordService, + ) {} + + @ApiBearerAuth() + @UseGuards(PermissionsGuard) + @Permissions('VISITOR_PASSWORD_ADD') + @Get() + @ApiOperation({ + summary: + ControllerRoute.VISITOR_PASSWORD.ACTIONS.GET_VISITOR_PASSWORD_SUMMARY, + description: + ControllerRoute.VISITOR_PASSWORD.ACTIONS.GET_VISITOR_PASSWORD_DESCRIPTION, + }) + async GetVisitorPassword(@Param() param: ProjectParam) { + return await this.visitorPasswordService.getPasswords(param); + } + + @ApiBearerAuth() + @UseGuards(PermissionsGuard) + @Permissions('VISITOR_PASSWORD_VIEW') + @Get('/devices') + @ApiOperation({ + summary: + ControllerRoute.VISITOR_PASSWORD.ACTIONS.GET_VISITOR_DEVICES_SUMMARY, + description: + ControllerRoute.VISITOR_PASSWORD.ACTIONS.GET_VISITOR_DEVICES_DESCRIPTION, + }) + async GetVisitorDevices(@Param() param: ProjectParam) { + return await this.visitorPasswordService.getAllPassDevices(param); + } +} diff --git a/src/vistor-password/controllers/visitor-password.controller.ts b/src/vistor-password/controllers/visitor-password.controller.ts index a298114..3e1b781 100644 --- a/src/vistor-password/controllers/visitor-password.controller.ts +++ b/src/vistor-password/controllers/visitor-password.controller.ts @@ -5,7 +5,6 @@ import { Post, HttpStatus, UseGuards, - Get, Req, } from '@nestjs/common'; import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger'; @@ -146,32 +145,4 @@ export class VisitorPasswordController { data: temporaryPassword, }; } - - @ApiBearerAuth() - @UseGuards(PermissionsGuard) - @Permissions('VISITOR_PASSWORD_VIEW') - @Get() - @ApiOperation({ - summary: - ControllerRoute.VISITOR_PASSWORD.ACTIONS.GET_VISITOR_PASSWORD_SUMMARY, - description: - ControllerRoute.VISITOR_PASSWORD.ACTIONS.GET_VISITOR_PASSWORD_DESCRIPTION, - }) - async GetVisitorPassword() { - return await this.visitorPasswordService.getPasswords(); - } - - @ApiBearerAuth() - @UseGuards(PermissionsGuard) - @Permissions('VISITOR_PASSWORD_VIEW') - @Get('/devices') - @ApiOperation({ - summary: - ControllerRoute.VISITOR_PASSWORD.ACTIONS.GET_VISITOR_DEVICES_SUMMARY, - description: - ControllerRoute.VISITOR_PASSWORD.ACTIONS.GET_VISITOR_DEVICES_DESCRIPTION, - }) - async GetVisitorDevices() { - return await this.visitorPasswordService.getAllPassDevices(); - } } diff --git a/src/vistor-password/dtos/index.ts b/src/vistor-password/dtos/index.ts index aa0f905..3bd7511 100644 --- a/src/vistor-password/dtos/index.ts +++ b/src/vistor-password/dtos/index.ts @@ -1 +1,2 @@ export * from './temp-pass.dto'; +export * from './project.param.dto'; \ No newline at end of file diff --git a/src/vistor-password/dtos/project.param.dto.ts b/src/vistor-password/dtos/project.param.dto.ts new file mode 100644 index 0000000..8bb2929 --- /dev/null +++ b/src/vistor-password/dtos/project.param.dto.ts @@ -0,0 +1,11 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsUUID } from 'class-validator'; + +export class ProjectParam { + @ApiProperty({ + description: 'UUID of the project this community belongs to', + example: 'd290f1ee-6c54-4b01-90e6-d701748f0851', + }) + @IsUUID() + projectUuid: string; +} diff --git a/src/vistor-password/services/visitor-password.service.ts b/src/vistor-password/services/visitor-password.service.ts index b8710fa..d0e1ff3 100644 --- a/src/vistor-password/services/visitor-password.service.ts +++ b/src/vistor-password/services/visitor-password.service.ts @@ -14,6 +14,7 @@ import { AddDoorLockOfflineOneTimeDto, AddDoorLockOnlineMultipleDto, AddDoorLockOnlineOneTimeDto, + ProjectParam, } from '../dtos'; import { EmailService } from '@app/common/util/email.service'; import { PasswordEncryptionService } from 'src/door-lock/services/encryption.services'; @@ -30,6 +31,7 @@ import { CommonHourMinutes, CommonHours, } from '@app/common/constants/hours-minutes.enum'; +import { ProjectRepository } from '@app/common/modules/project/repositiories'; @Injectable() export class VisitorPasswordService { @@ -42,6 +44,7 @@ export class VisitorPasswordService { private readonly doorLockService: DoorLockService, private readonly deviceService: DeviceService, private readonly passwordEncryptionService: PasswordEncryptionService, + private readonly projectRepository: ProjectRepository, ) { const accessKey = this.configService.get('auth-config.ACCESS_KEY'); const secretKey = this.configService.get('auth-config.SECRET_KEY'); @@ -444,12 +447,21 @@ export class VisitorPasswordService { ); } } - async getPasswords() { + async getPasswords(param: ProjectParam) { + await this.validateProject(param.projectUuid); + const deviceIds = await this.deviceRepository.find({ where: { productDevice: { prodType: ProductType.DL, }, + spaceDevice: { + community: { + project: { + uuid: param.projectUuid, + }, + }, + }, isActive: true, }, }); @@ -487,14 +499,24 @@ export class VisitorPasswordService { }); } - async getAllPassDevices() { + async getAllPassDevices(param: ProjectParam) { + await this.validateProject(param.projectUuid); + const devices = await this.deviceRepository.find({ where: { productDevice: { prodType: ProductType.DL, }, + spaceDevice: { + community: { + project: { + uuid: param.projectUuid, + }, + }, + }, isActive: true, }, + relations: ['productDevice'], }); const devicesData = await Promise.all( @@ -907,4 +929,17 @@ export class VisitorPasswordService { ); } } + + private async validateProject(uuid: string) { + const project = await this.projectRepository.findOne({ + where: { uuid }, + }); + if (!project) { + throw new HttpException( + `A project with the uuid '${uuid}' doesn't exists.`, + HttpStatus.BAD_REQUEST, + ); + } + return project; + } } diff --git a/src/vistor-password/visitor-password.module.ts b/src/vistor-password/visitor-password.module.ts index 3aaf3a5..5ee1f0e 100644 --- a/src/vistor-password/visitor-password.module.ts +++ b/src/vistor-password/visitor-password.module.ts @@ -21,9 +21,11 @@ import { } from '@app/common/modules/scene/repositories'; import { SceneDeviceRepository } from '@app/common/modules/scene-device/repositories'; import { AutomationRepository } from '@app/common/modules/automation/repositories'; +import { ProjectRepository } from '@app/common/modules/project/repositiories'; +import { VisitorPasswordProjectController } from './controllers'; @Module({ imports: [ConfigModule, DeviceRepositoryModule, DoorLockModule], - controllers: [VisitorPasswordController], + controllers: [VisitorPasswordController, VisitorPasswordProjectController], providers: [ VisitorPasswordService, EmailService, @@ -41,6 +43,7 @@ import { AutomationRepository } from '@app/common/modules/automation/repositorie SceneRepository, SceneDeviceRepository, AutomationRepository, + ProjectRepository, ], exports: [VisitorPasswordService], }) From 2dcce3cce31cd40e934fee935c42b64a797b6bd4 Mon Sep 17 00:00:00 2001 From: hannathkadher Date: Sun, 16 Feb 2025 23:30:14 +0400 Subject: [PATCH 7/7] roll back --- .github/workflows/main_syncrow(staging).yml | 84 +++++++++++---------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/.github/workflows/main_syncrow(staging).yml b/.github/workflows/main_syncrow(staging).yml index 0d29d1b..ea5d088 100644 --- a/.github/workflows/main_syncrow(staging).yml +++ b/.github/workflows/main_syncrow(staging).yml @@ -1,7 +1,4 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy container app to Azure Web App - syncrow(staging) +name: Backend deployment to Azure App Service on: push: @@ -9,43 +6,50 @@ on: - main workflow_dispatch: +env: + AZURE_WEB_APP_NAME: 'syncrow' + AZURE_WEB_APP_SLOT_NAME: 'staging' + ACR_REGISTRY: 'syncrow.azurecr.io' + IMAGE_NAME: 'backend' + IMAGE_TAG: 'latest' + jobs: - build: - runs-on: 'ubuntu-latest' - - steps: - - uses: actions/checkout@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Log in to registry - uses: docker/login-action@v2 - with: - registry: https://syncrow.azurecr.io/ - username: ${{ secrets.AzureAppService_ContainerUsername_47395803300340b49931ea82f6d80be3 }} - password: ${{ secrets.AzureAppService_ContainerPassword_e7b0ff54f54d44cba04a970a22384848 }} - - - name: Build and push container image to registry - uses: docker/build-push-action@v3 - with: - push: true - tags: syncrow.azurecr.io/${{ secrets.AzureAppService_ContainerUsername_47395803300340b49931ea82f6d80be3 }}/syncrow/backend:${{ github.sha }} - file: ./Dockerfile - - deploy: + build_and_deploy: runs-on: ubuntu-latest - needs: build - environment: - name: 'staging' - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} steps: - - name: Deploy to Azure Web App - id: deploy-to-webapp - uses: azure/webapps-deploy@v2 - with: - app-name: 'syncrow' - slot-name: 'staging' - publish-profile: ${{ secrets.AzureAppService_PublishProfile_44f7766441ec4796b74789e9761ef589 }} - images: 'syncrow.azurecr.io/${{ secrets.AzureAppService_ContainerUsername_47395803300340b49931ea82f6d80be3 }}/syncrow/backend:${{ github.sha }}' \ No newline at end of file + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + - name: Install dependencies and build project + run: | + npm install + npm run build + + - name: Log in to Azure + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Log in to Azure Container Registry + run: az acr login --name ${{ env.ACR_REGISTRY }} + + - name: List build output + run: ls -R dist/ + + - name: Build and push Docker image + run: | + docker build . -t ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} + docker push ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} + + - name: Set Web App with Docker container + run: | + az webapp config container set \ + --name ${{ env.AZURE_WEB_APP_NAME }} \ + --resource-group backend \ + --docker-custom-image-name ${{ env.ACR_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} \ + --docker-registry-server-url https://${{ env.ACR_REGISTRY }} \ No newline at end of file