diff --git a/docsfera.json b/docsfera.json index 11db613..62d13f3 100644 --- a/docsfera.json +++ b/docsfera.json @@ -5,6 +5,265 @@ "schema": { "openapi": "3.0.0", "paths": { + "/auth/sign-in": { + "post": { + "operationId": "AuthController_signIn", + "parameters": [ + { + "name": "Dadosfera-Lang", + "required": true, + "in": "header", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthSignInReq" + } + } + } + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthSignInRes" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/sso/snowflake": { + "post": { + "operationId": "AuthController_snowflakeSignIn", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/refresh-access-token": { + "post": { + "operationId": "AuthController_refreshAccessToken", + "parameters": [ + { + "name": "Dadosfera-Lang", + "required": true, + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/change-password": { + "post": { + "operationId": "AuthController_changePassword", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/reset-password": { + "post": { + "operationId": "AuthController_resetPassword", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/verify-reset-password-code": { + "post": { + "operationId": "AuthController_verifyResetPasswordCode", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/confirm-reset-password": { + "post": { + "operationId": "AuthController_confirmResetPassword", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/enable-totp": { + "post": { + "operationId": "AuthController_enableTotpMFA", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/disable-totp": { + "post": { + "operationId": "AuthController_disableTotpMFA", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/dismiss-totp": { + "post": { + "operationId": "AuthController_dismissTotpMFA", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, + "/auth/verify-totp": { + "post": { + "operationId": "AuthController_verifyTotp", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "tags": [ + "Auth" + ] + } + }, "/connectors": { "post": { "operationId": "ConnectorController_uploadConnector", @@ -385,255 +644,6 @@ ] } }, - "/auth/sso/snowflake": { - "post": { - "operationId": "AuthController_snowflakeSignIn", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/sign-in": { - "post": { - "operationId": "AuthController_signIn", - "parameters": [ - { - "name": "Dadosfera-Lang", - "required": true, - "in": "header", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/refresh-access-token": { - "post": { - "operationId": "AuthController_refreshAccessToken", - "parameters": [ - { - "name": "Dadosfera-Lang", - "required": true, - "in": "header", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/change-password": { - "post": { - "operationId": "AuthController_changePassword", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/reset-password": { - "post": { - "operationId": "AuthController_resetPassword", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/verify-reset-password-code": { - "post": { - "operationId": "AuthController_verifyResetPasswordCode", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/confirm-reset-password": { - "post": { - "operationId": "AuthController_confirmResetPassword", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/enable-totp": { - "post": { - "operationId": "AuthController_enableTotpMFA", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/disable-totp": { - "post": { - "operationId": "AuthController_disableTotpMFA", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/dismiss-totp": { - "post": { - "operationId": "AuthController_dismissTotpMFA", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, - "/auth/verify-totp": { - "post": { - "operationId": "AuthController_verifyTotp", - "parameters": [], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - }, - "tags": [ - "Auth" - ] - } - }, "/permissions": { "get": { "operationId": "PermissionsController_getPublicPermissions", @@ -3290,7 +3300,7 @@ "info": { "title": "Maestro - fix/pipeline-details-bug", "description": "Documentation for Maestro gateway", - "version": "9.11.2022 - 20:4", + "version": "10.11.2022 - 9:44", "contact": {} }, "tags": [], @@ -3304,6 +3314,176 @@ } }, "schemas": { + "AuthSignInReq": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "totp": { + "type": "string" + } + }, + "required": [ + "username", + "password" + ] + }, + "AuthCustomer": { + "type": "object", + "properties": { + "modules": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "modules", + "id", + "name", + "tier" + ] + }, + "AuthUser": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "username": { + "type": "string" + }, + "createdAt": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "username", + "createdAt" + ] + }, + "AuthTokens": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "termsOfUseToken": { + "type": "string" + }, + "idToken": { + "type": "string", + "deprecated": true + } + }, + "required": [ + "accessToken", + "refreshToken", + "idToken" + ] + }, + "TermsOfUse": { + "type": "object", + "properties": { + "version": { + "type": "number" + }, + "publicUrl": { + "type": "string" + }, + "enforceDate": { + "type": "string" + }, + "createdAt": { + "type": "string" + } + }, + "required": [ + "version", + "publicUrl", + "enforceDate", + "createdAt" + ] + }, + "TermsOfUseStatus": { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": [ + "pending", + "required", + "ok" + ] + }, + "lastSigned": { + "$ref": "#/components/schemas/TermsOfUse" + }, + "next": { + "$ref": "#/components/schemas/TermsOfUse" + } + }, + "required": [ + "status" + ] + }, + "AuthSignInRes": { + "type": "object", + "properties": { + "permissions": { + "type": "array", + "items": { + "type": "string" + } + }, + "mfaStatus": { + "type": "string", + "enum": [ + "pending", + "none", + "totp" + ] + }, + "customer": { + "$ref": "#/components/schemas/AuthCustomer" + }, + "user": { + "$ref": "#/components/schemas/AuthUser" + }, + "tokens": { + "$ref": "#/components/schemas/AuthTokens" + }, + "termsOfUse": { + "$ref": "#/components/schemas/TermsOfUseStatus" + } + }, + "required": [ + "permissions", + "mfaStatus" + ] + }, "CreateConnectorDto": { "type": "object", "properties": { diff --git a/src/app.module.ts b/src/app.module.ts index 9905c93..d736888 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -39,8 +39,8 @@ import { MixpanelModule } from './modules/mixpanel/mixpanel.module'; ConfigModule.forRoot({ isGlobal: true, }), - ConnectorModule, AuthModule, + ConnectorModule, PermissionsModule, TermsOfUseModule, ConnectionModule, diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index 4e4714c..503dc64 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -10,7 +10,6 @@ import { } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { - AuthSignInRequest, AuthRefreshAccessTokenRequest, AuthChangePasswordRequest, AuthResetPasswordRequest, @@ -28,6 +27,7 @@ import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { GrpcToHttpExceptionFilter } from '../../error/grpc-to-http-exception.filter'; import { RequestUser, User } from 'src/authentication/user.decorator'; import { Metadata } from '@grpc/grpc-js'; +import { AuthSignInReq, AuthSignInRes } from './dtos/login'; @ApiTags('Auth') @UseFilters(new GrpcToHttpExceptionFilter()) @@ -43,6 +43,18 @@ export class AuthController { this.logger = dadosferaLogger.logger; } + @Post('sign-in') + @HttpCode(HttpStatus.OK) + async signIn( + @Body() { username, password, totp }: AuthSignInReq, + @Headers('Dadosfera-Lang') language: string, + ): Promise { + this.logger.info('/auth - SignIn'); + const metadata = new Metadata(); + metadata.add('language', language || 'pt-br'); + return this.authClient.signIn({ username, password, totp }, metadata); + } + @Post('/sso/snowflake') @RequireAllPermissions(PERMISSIONS_GROUPS.SNOWFLAKE.permissions.OPEN) @HttpCode(HttpStatus.OK) @@ -58,18 +70,6 @@ export class AuthController { }); } - @Post('sign-in') - @HttpCode(HttpStatus.OK) - async signIn( - @Body() { username, password, totp }: AuthSignInRequest, - @Headers('Dadosfera-Lang') language: string, - ) { - this.logger.info('/auth - SignIn'); - const metadata = new Metadata(); - metadata.add('language', language || 'pt-br'); - return this.authClient.signIn({ username, password, totp }, metadata); - } - @Post('refresh-access-token') @HttpCode(HttpStatus.OK) async refreshAccessToken( diff --git a/src/modules/auth/dtos/login.ts b/src/modules/auth/dtos/login.ts index cae27fd..32e1885 100644 --- a/src/modules/auth/dtos/login.ts +++ b/src/modules/auth/dtos/login.ts @@ -1,4 +1,8 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { + AuthSignInRequest, + AuthSignInResponse, +} from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class LoginDto { @ApiProperty() @@ -10,3 +14,86 @@ export class LoginDto { @ApiProperty({ required: false }) totp: string; } +export class AuthTokens { + @ApiProperty() + accessToken: string; + @ApiProperty() + refreshToken: string; + @ApiPropertyOptional() + termsOfUseToken: string; + @ApiProperty({ deprecated: true }) + idToken: string; +} +export enum MfaStatuses { + PENDING = 'pending', + NONE = 'none', + TOTP = 'totp', +} + +export enum TouStatuses { + PENDING = 'pending', + REQUIRED = 'required', + OK = 'ok', +} +export class TermsOfUse { + @ApiProperty() + version: number; + @ApiProperty() + publicUrl: string; + @ApiProperty() + enforceDate: string; + @ApiProperty() + createdAt: string; +} +export class TermsOfUseStatus { + @ApiProperty({ enum: TouStatuses }) + status: string; + @ApiPropertyOptional() + lastSigned?: TermsOfUse; + @ApiPropertyOptional() + next?: TermsOfUse; +} +export class AuthUser { + @ApiProperty() + id: string; + @ApiProperty() + name: string; + @ApiProperty() + username: string; + @ApiProperty() + createdAt: string; +} +export class AuthCustomer { + @ApiProperty() + modules: string[]; + @ApiProperty() + id: string; + @ApiProperty() + name: string; + @ApiProperty() + tier: string; +} + +export class AuthSignInReq implements AuthSignInRequest { + @ApiProperty() + username: string; + @ApiProperty() + password: string; + @ApiPropertyOptional() + totp: string; +} + +export class AuthSignInRes implements AuthSignInResponse { + @ApiProperty() + permissions: string[]; + @ApiProperty({ enum: MfaStatuses }) + mfaStatus: string; + @ApiPropertyOptional() + customer?: AuthCustomer; + @ApiPropertyOptional() + user?: AuthUser; + @ApiPropertyOptional() + tokens?: AuthTokens; + @ApiPropertyOptional() + termsOfUse?: TermsOfUseStatus; +} diff --git a/tsconfig.build.json b/tsconfig.build.json index 64f86c6..ca83a6b 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,4 +1,4 @@ { "extends": "./tsconfig.json", - "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] + "exclude": ["node_modules", "test", "dist", "**/*spec.ts", "jest.config.ts"] }