Merged in feature/login-v2 (pull request #36)

Feature/login v2
This commit is contained in:
Peter Maquiran
2025-06-03 08:46:54 +00:00
137 changed files with 2201 additions and 1476 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest package="com.gpr.gabinetedigital" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+3 -5
View File
@@ -57,15 +57,15 @@ The project is divided into several key sections, each serving a specific purpos
├── src
│ ├── common
│ ├── core
│ │ ├── attachment
│ │ ├── chat
│ │ │ ├── entity
│ │ │ ├── repository
│ │ │ └── use-cases
│ ├── module
│ │ ├── gabinete
│ │ ├── agenda
│ │ │ ├── domain
│ │ │ ├── data
│ │ ├── Agenda
│ │ ├── chat
│ │ │ ├── domain
│ │ │ ├── data
│ ├── UI
@@ -77,8 +77,6 @@ The project is divided into several key sections, each serving a specific purpos
│ │ │ | ├── service
│ │ │ │ └── store
│ │ │ ├── Agenda
│ │ │ ├── Gabinete
│ │ │ ├── Actions
│ │ │ ├── Chat
│ ├── infra
│ │ ├── http
+4
View File
@@ -30,6 +30,9 @@ Java version 11
ionic build &&
npx cap add android &&
npx cap update
Gradle version 7.4.1
Gradle SDK JDK 16.0.2
## BUG
@@ -97,3 +100,4 @@ git tag stable
For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
-16
View File
@@ -1,16 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(UserService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
-12
View File
@@ -1,12 +0,0 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor() { }
changeProfilePicture(){}
}
+24
View File
@@ -9,6 +9,7 @@ import { Storage } from '@ionic/storage';
import { register } from 'swiper/element/bundle';
import { DomSanitizer } from '@angular/platform-browser';
import { ScreenOrientation } from "@ionic-native/screen-orientation/ngx";
import { SessionStore } from './store/session.service';
const CUSTOM_DATE_FORMATS: NgxMatDateFormats = {
parse: {
dateInput: "YYYY-MMMM-DD HH:mm"
@@ -31,6 +32,8 @@ register();
]
})
export class AppComponent {
tabIsActive = true
constructor(
private platform: Platform,
private statusBar: StatusBar,
@@ -67,6 +70,27 @@ export class AppComponent {
}
}
window.addEventListener('focus', (event) => {
if (!this.tabIsActive) {
this.tabIsActive = true
const data = SessionStore.getDataFromLocalStorage();
if (!data?.user?.Authorization && SessionStore?.user?.Authorization) {
window.location.reload();
}
if (window['all-process-gabinete']) {
window['all-process-gabinete']()
}
}
});
window.addEventListener('blur', (event) => {
this.tabIsActive = false
});
}
/* requestPermission() {
+5 -5
View File
@@ -86,15 +86,14 @@ import { CreateProcessPage } from './modals/create-process/create-process.page';
import { LoggingInterceptorService } from './services/logging-interceptor.service';
import { PopupQuestionPipe } from './modals/popup-question.pipe';
import '@teamhive/capacitor-video-recorder';
import { tokenInterceptor } from './interceptors/token.interceptors';
import { chatTokenInterceptor } from './interceptors/chatToken.interceptor';
import { tokenInterceptor } from './infra/monitoring/interceptors/token.interceptors';
import { InputFilterDirective } from './services/directives/input-filter.directive';
import { VisibilityDirective } from './services/directives/visibility.directive';
import { DeplomaOptionsPageModule } from './shared/popover/deploma-options/deploma-options.module';
import { DiplomaOptionsPage } from './shared/popover/deploma-options/deploma-options.page';
import { ImageCropperModule } from 'ngx-image-cropper';
import { metricsInterceptor } from './interceptors/metter.interceptor';
import { metricsInterceptor } from './infra/monitoring/interceptors/metter.interceptor';
import {MatMenuModule} from '@angular/material/menu';
import {MatIconModule} from '@angular/material/icon';
@@ -104,6 +103,7 @@ import { openTelemetryLogging } from './services/monitoring/opentelemetry/loggin
import { registerLocaleData } from '@angular/common';
import localePt from '@angular/common/locales/pt';
import { LogsDatabase } from './infra/database/dexie/instance/logs/service';
import { UserModule } from './module/user/user.module';
// Register the locale data
registerLocaleData(localePt, 'pt');
@@ -209,7 +209,8 @@ registerLocaleData(localePt, 'pt');
MatMenuModule,
MatIconModule,
// module
ChatModule
ChatModule,
UserModule
],
entryComponents: [
DiplomaOptionsPage,
@@ -251,7 +252,6 @@ registerLocaleData(localePt, 'pt');
FFMpeg,
FFmpeg,
{ provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptorService, multi: true },
chatTokenInterceptor,
tokenInterceptor,
metricsInterceptor
],
+4 -2
View File
@@ -95,9 +95,11 @@ export class MessageEntity {
constructor() {}
get messageStatus() {
get messageHasId() {
if(this.id) {
return 'send'
return true
} else {
return false
}
}
@@ -5,8 +5,19 @@ import { RoomByIdInputDTO, RoomByIdOutputDTO } from "src/app/core/chat/usecase/r
import { RoomUpdateInputDTO, RoomUpdateOutputDTO } from "src/app/core/chat/usecase/room/room-update-by-id-use-case.service";
import { Result } from "neverthrow";
import { AddMemberToRoomInputDTO } from "src/app/core/chat/usecase/member/member-add-use-case.service";
import { RoomListOutPutDTO } from "src/app/core/chat/usecase/room/room-get-list-use-case.service";
import { RoomListItemOutPutDTO, RoomListItemSchema, RoomListOutPutDTO } from "src/app/core/chat/usecase/room/room-get-list-use-case.service";
export interface ISearchRoom {
success: boolean,
message: any,
data: {
messages: [],
rooms: RoomListItemSchema[]
}
}
export abstract class IRoomRemoteRepository {
abstract createRoom(data: CreateRoomInputDTO): DataSourceReturn<RoomOutPutDTO>
abstract getRoomList(): Promise<DataSourceReturn<RoomListOutPutDTO>>
@@ -14,4 +25,5 @@ export abstract class IRoomRemoteRepository {
abstract updateRoom(data: RoomUpdateInputDTO): Promise<DataSourceReturn<RoomUpdateOutputDTO>>
abstract deleteRoom(id: string): Promise<Result<any ,any>>
abstract addMemberToRoomSocket(data: AddMemberToRoomInputDTO): Promise<Result<any ,any>>
abstract search(input: string): Promise<Result<RoomListItemOutPutDTO[], any>>
}
@@ -0,0 +1,236 @@
import { Injectable } from '@angular/core';
import { IMessage, MessageAttachmentSource, MessageEntity, MessageEntitySchema, } from '../../entity/message';
import { z } from 'zod';
import { v4 as uuidv4 } from 'uuid';
import { InstanceId } from '../../../../module/chat/domain/chat-service.service';
import { createBlobFromBase64, createDataURL } from 'src/app/utils/ToBase64';
import { zodSafeValidation } from 'src/app/utils/zodValidation';
import { Logger } from 'src/app/services/logger/main/service';
import { err, Result } from 'neverthrow';
import { MessageMapper } from '../../mapper/messageMapper';
import { RoomType } from "src/app/core/chat/entity/group";
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
import { MessageAttachmentFileType, MessageOutPutDataDTO } from 'src/app/core/chat/repository/dto/messageOutputDTO';
import { IMessageLocalRepository } from 'src/app/core/chat/repository/message/message-local-repository';
import { IMessageSocketRepository } from 'src/app/core/chat/repository/message/message-socket-repository';
import { IMemberLocalRepository } from 'src/app/core/chat/repository/member/member-local-repository';
import { IAttachmentLocalRepository } from 'src/app/core/chat/repository/typing/typing-local-repository';
import { base64Schema } from 'src/app/utils/zod';
export const MessageInputDTOSchema = z.object({
roomId: z.string().uuid().optional(),
receiverId: z.number().optional(),
senderId: z.number(),
message: z.string().nullable().optional(),
messageType: z.number(),
canEdit: z.boolean(),
oneShot: z.boolean(),
requireUnlock: z.boolean(),
requestId: z.string(),
attachment: z.object({
fileType: z.nativeEnum(MessageAttachmentFileType),
source: z.nativeEnum(MessageAttachmentSource),
file: base64Schema.optional(),
fileName: z.string().optional(),
applicationId: z.number().optional(),
docId: z.number().optional(),
mimeType: z.string().nullable().optional(),
description: z.string().optional()
}).optional()
});
export type MessageInputDTO = z.infer<typeof MessageInputDTOSchema>
export const MessageCreatePutDataDTOSchema = z.object({
id: z.string(),
roomId: z.string(),
sender: z.object({
wxUserId: z.number(),
wxFullName: z.string(),
wxeMail: z.string(),
userPhoto: z.string().optional()
}),
message: z.string().nullable().optional(),
messageType: z.number(),
sentAt: z.string(),
canEdit: z.boolean(),
oneShot: z.boolean(),
requireUnlock: z.boolean(),
requestId: z.string().optional().nullable(),
reactions: z.object({
id: z.string(),
reactedAt: z.string(),
reaction: z.string(),
sender: z.object({}),
}).array(),
info: z.array(z.object({
memberId: z.number(),
readAt: z.string().nullable(),
deliverAt: z.string().nullable()
})),
attachments: z.array(z.object({
fileType: z.nativeEnum(MessageAttachmentFileType),
source: z.nativeEnum(MessageAttachmentSource),
file: z.string().optional(),
fileName: z.string().optional(),
applicationId: z.number().optional(),
docId: z.number().optional(),
id: z.string().optional()
}))
});
export type MessageCreateOutPutDataDTO = z.infer<typeof MessageCreatePutDataDTOSchema>
@Injectable({
providedIn: 'root'
})
export class MessageCreateUseCaseService {
constructor(
private AttachmentLocalRepositoryService: IAttachmentLocalRepository,
private messageLocalDataSourceService: IMessageLocalRepository,
private messageSocketRepositoryService: IMessageSocketRepository,
private MemberListLocalRepository: IMemberLocalRepository
) { }
@XTracerAsync({name:'MessageCreateUseCaseService', module:'chat', bugPrint: true, waitNThrow: 5000})
async execute(message: IMessage, messageEnum: RoomType, tracing?: TracingType) {
const validation = zodSafeValidation<IMessage>(MessageEntitySchema, message)
if(validation.isOk()) {
message.sendAttemp++;
message.requestId = InstanceId +'@'+ uuidv4();
message.sending = true;
const createMessageLocally = this.messageLocalDataSourceService.insert(message)
createMessageLocally.then(async (value) => {
if(value.isOk()) {
const localId = value.value
message.$id = localId
if(message.hasAttachment) {
for (const attachment of message.attachments) {
if(attachment.source != MessageAttachmentSource.Webtrix) {
this.AttachmentLocalRepositoryService.insert({
$messageId: localId,
file: createBlobFromBase64(attachment.file, attachment.mimeType),
fileType: attachment.fileType,
source: attachment.source,
fileName: attachment.fileName,
applicationId: attachment.applicationId,
docId: attachment.docId,
mimeType: attachment.mimeType,
base64: createDataURL(attachment.file, attachment.mimeType)
}).then((e) => {
if(e.isErr()) {
Logger.error('failed to create attachment locally on send message', {
error: e.error,
data: createDataURL(attachment.file, attachment.mimeType).slice(0, 100) +'...'
})
}
})
attachment.safeFile = createDataURL(attachment.file, attachment.mimeType)
}
}
}
} else {
Logger.error('failed to insert locally', {
error: value.error.message
})
}
}).catch((error) => {
Logger.error('failed to insert catch', {
//error: createMessageLocally.error.message
})
})
let sendMessageResult: Result<MessageOutPutDataDTO, any>
if(messageEnum == RoomType.Group) {
const DTO = MessageMapper.fromDomain(message, message.requestId)
message.sending = true
sendMessageResult = await this.messageSocketRepositoryService.sendGroupMessage(DTO)
} else {
const DTO = MessageMapper.fromDomain(message, message.requestId)
delete DTO.roomId
message.sending = true
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
}
// return this sendMessageResult
if(sendMessageResult.isOk()) {
message.id = sendMessageResult.value.id
console.log('sendMessageResult', sendMessageResult.value.id)
if(sendMessageResult.value.sender == undefined || sendMessageResult.value.sender == null) {
delete sendMessageResult.value.sender
}
let clone: MessageTable = {
...sendMessageResult.value,
id: sendMessageResult.value.id,
$id : message.$id
}
createMessageLocally.then(() => {
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: clone.roomId}).then((data)=> {
if(data.isOk()) {
} else {
tracing.hasError('failed to update send message')
console.log(sendMessageResult)
console.log(data.error)
}
})
})
return sendMessageResult
} else {
Logger.error('failed to send message to the server', {
error: sendMessageResult.error
})
await this.messageLocalDataSourceService.update(message.$id, {sending: false, $id: message.$id})
return err('no connection')
}
} else {
if(validation.error.formErrors.fieldErrors.attachments) {
Logger.error('failed to send message doe to invalid attachment', {
zodErrorList: validation.error.errors,
data: message.attachments
})
} else {
Logger.error('failed to send message, validation failed', {
zodErrorList: validation.error.errors,
data: message
})
}
}
}
}
@@ -106,13 +106,14 @@ export class MessageCreateUseCaseService {
message.sendAttemp++;
message.requestId = InstanceId +'@'+ uuidv4();
message.sending = true;
const createMessageLocally = await this.messageLocalDataSourceService.insert(message)
const createMessageLocally = this.messageLocalDataSourceService.insert(message)
if(createMessageLocally.isOk()) {
createMessageLocally.then((value) => {
if(value.isOk()) {
message.$id = createMessageLocally.value
console.log("set image")
message.$id = value.value
if(message.hasAttachment) {
@@ -121,7 +122,7 @@ export class MessageCreateUseCaseService {
if(attachment.source != MessageAttachmentSource.Webtrix) {
this.AttachmentLocalRepositoryService.insert({
$messageId: createMessageLocally.value,
$messageId: value.value,
file: createBlobFromBase64(attachment.file, attachment.mimeType),
fileType: attachment.fileType,
source: attachment.source,
@@ -146,10 +147,20 @@ export class MessageCreateUseCaseService {
}
} else {
Logger.error('failed to insert locally', {
error: value.error.message
})
}
});
//====================
message.sending = true
let sendMessageResult: Result<MessageOutPutDataDTO, any>
let sendMessageResult!: Result<MessageOutPutDataDTO, any>
const start = performance.now(); // Capture the start time
if(messageEnum == RoomType.Group) {
const DTO = MessageMapper.fromDomain(message, message.requestId)
sendMessageResult = await this.messageSocketRepositoryService.sendGroupMessage(DTO)
@@ -159,6 +170,11 @@ export class MessageCreateUseCaseService {
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
}
const end = performance.now(); // Capture the end time
const duration = end - start; // Calculate the difference
tracing.setAttribute("duration", `Execution time: ${duration}ms`);
// return this sendMessageResult
if(sendMessageResult.isOk()) {
@@ -172,12 +188,14 @@ export class MessageCreateUseCaseService {
delete sendMessageResult.value.sender
}
createMessageLocally.then((value) => {
console.log('sendMessageResult', (sendMessageResult as any).value)
let clone: MessageTable = {
...sendMessageResult.value,
id: sendMessageResult.value.id,
...(sendMessageResult as any).value,
id: (sendMessageResult as any).value.id,
$id : message.$id
}
console.log('set update')
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: clone.roomId}).then((data)=> {
if(data.isOk()) {
@@ -187,6 +205,8 @@ export class MessageCreateUseCaseService {
console.log(data.error)
}
})
});
return sendMessageResult
} else {
@@ -196,12 +216,6 @@ export class MessageCreateUseCaseService {
await this.messageLocalDataSourceService.update(message.$id, {sending: false, $id: message.$id})
return err('no connection')
}
} else {
Logger.error('failed to insert locally', {
error: createMessageLocally.error.message
})
}
} else {
if(validation.error.formErrors.fieldErrors.attachments) {
@@ -4,6 +4,9 @@ import { ValidateSchema } from 'src/app/services/decorators/validate-schema.deco
import { MessageRemoteDataSourceService } from '../../../../module/chat/data/repository/message/message-remote-data-source.service';
import { MessageSocketRepositoryService } from '../../../../module/chat/data/repository/message/message-live-signalr-data-source.service';
import { IMessageSocketRepository } from '../../repository/message/message-socket-repository';
import { zodSafeValidation } from 'src/app/utils/zodValidation';
import { Logger } from 'src/app/services/logger/main/service';
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
const MessageUpdateInputDTOSchema = z.object({
@@ -26,9 +29,23 @@ export class MessageUpdateUseCaseService {
public repository: IMessageSocketRepository
) { }
@ValidateSchema(MessageUpdateInputDTOSchema)
execute(input: MessageUpdateInput) {
return this.repository.updateMessage(input);
@XTracerAsync({name:'MessageUpdateUseCaseService', module:'chat', bugPrint: true, waitNThrow: 5000})
async execute(input: MessageUpdateInput, tracing?: TracingType) {
console.log('MessageUpdateUseCaseService', input)
const validation = zodSafeValidation<MessageUpdateInput>(MessageUpdateInputDTOSchema, input)
if(validation.isOk()) {
} else {
tracing.hasError('failed to update message, validation failed')
Logger.error('failed to update message, validation failed', {
zodErrorList: validation.error.errors,
data: input
})
}
return await this.repository.updateMessage(input);
}
}
@@ -19,8 +19,7 @@ const CreatedBySchema = z.object({
userPhoto: z.string().nullable()// api check
});
const RoomListItemOutPutDTOSchema = z.object({
chatRoom: z.object({
const roomListItemSchema = z.object({
id: z.string(),
roomName: z.string(),
createdBy: CreatedBySchema,
@@ -30,7 +29,10 @@ const RoomListItemOutPutDTOSchema = z.object({
messages: MessageEntitySchema.array(),
user1: CreatedBySchema.nullable(),
user2: CreatedBySchema.nullable()
}),
})
const RoomListItemOutPutDTOSchema = z.object({
chatRoom: roomListItemSchema,
joinAt: z.string()
})
@@ -43,7 +45,7 @@ export const RoomListOutPutDTOSchema = z.object({
});
export type RoomListItemOutPutDTO = z.infer<typeof RoomListItemOutPutDTOSchema>
export type RoomListItemSchema = z.infer< typeof roomListItemSchema>
export type RoomListOutPutDTO = z.infer<typeof RoomListOutPutDTOSchema>
@@ -60,7 +62,6 @@ export class GetRoomListUseCaseService {
@captureAndReraiseAsync('RoomRepositoryService/list')
async execute() {
// console.log('update===============')
const result = await this.roomRemoteDataSourceService.getRoomList()
const localList = await this.roomLocalDataSourceService.findAll()
@@ -90,7 +91,7 @@ export class GetRoomListUseCaseService {
// console.log({roomsToDelete, roomsToInsert, roomsToUpdate})
// sometime api return duplicated rooms
const insertedIds = []
const insertedIds: string[] = []
if(roomsToInsert) {
const roomsToInsertEntity = GetRoomListMapper.toDomain(roomsToInsert)
@@ -114,7 +115,7 @@ export class GetRoomListUseCaseService {
} else {
// prevent to insert the same room due to server duplication
if(!insertedIds.find(e => room.id)) {
if(!insertedIds.find(e => room.id == e)) {
const createResult = this.roomLocalDataSourceService.insert(room)
@@ -122,9 +123,13 @@ export class GetRoomListUseCaseService {
createResult.then((result) => {
if(result.isErr()) {
console.log('error', result.error)
console.error('error', result.error)
}
}).catch(e => {
console.error('error on insert', e);
})
} else {
console.error('server duplication', room.id, insertedIds.toString())
}
}
@@ -0,0 +1,17 @@
import { Injectable } from '@angular/core';
import { IRoomRemoteRepository } from '../../repository/room/room-remote-repository';
@Injectable({
providedIn: 'root'
})
export class RoomSearchByNameService {
constructor(
private roomRemoteDataSourceService: IRoomRemoteRepository
) { }
async execute(name: string) {
const result = this.roomRemoteDataSourceService.search(name)
}
}
@@ -0,0 +1,21 @@
import { Injectable } from '@angular/core';
import { RemoteNotificationService } from 'src/app/module/notification/data/datasource/remote-notification.service';
import { SessionStore } from 'src/app/store/session.service';
import { z } from 'zod';
const NotificationDeleteAllByUserIdSchema = z.any()
export type INotificationDeleteAllByUserId = z.infer<typeof NotificationDeleteAllByUserIdSchema>
@Injectable({
providedIn: 'root'
})
export class NotificationDeleteAllServiceUseCase {
constructor(
private RemoteNotificationService:RemoteNotificationService
) { }
async execute() {
return this.RemoteNotificationService.notificationDeleteAll(SessionStore.user.UserId)
}
}
+6
View File
@@ -0,0 +1,6 @@
export class Preference {
LoginPreference = null
UrlBeforeInactivity= ''
Inactivity= true
PIN = ''
}
+139
View File
@@ -0,0 +1,139 @@
// import { z } from "zod";
// // Define the schema for the user object
// const UserSchema = z.object({
// wxUserId: z.number(),
// wxFullName: z.string(),
// wxeMail: z.string(),
// role: z.string(),
// roleId: z.number(),
// userPhoto: z.string(),
// adUserSID: z.string(),
// });
// // Define the schema for the main response object
// const UserDataSchema = z.object({
// user: UserSchema,
// authorization: z.string(),
// refreshToken: z.string(),
// permissions: z.array(z.number()),
// });
// export type IUser = z.infer<typeof UserDataSchema>
// export class UserEntity {
// wxUserId: number
// wxFullName: string
// wxeMail: string
// role: string
// roleId: number
// userPhoto: string
// adUserSID: string
// authorization: string
// refreshToken: string
// permissions: number[]
// Profile: 'PR' | 'MDGPR'| 'Consultant'| 'SGGPR'| 'Unknown'
// constructor(input: IUser) {
// Object.assign(this, input)
// if (input) {
// if (input?.user?.roleId == 100000014) {
// this.Profile = 'PR'
// } else if (input.user.roleId == 100000011) {
// this.Profile = 'MDGPR'
// } else if (input.user.roleId == 99999872) {
// this.Profile = 'Consultant'
// } else if (input.user.roleId == 99999886) {
// this.Profile = 'SGGPR'
// } else {
// this.Profile = 'Unknown'
// }
// }
// }
// }
import { z } from 'zod';
const LoginUserResponseSchema = z.object({
UserId: z.number(),
Authorization: z.string(),
Email: z.string().email(),
FullName: z.string(),
RoleDescription: z.string(),
RoleID: z.number(),
Profile: z.string(), // You can further define the Profile if you have more details
UserPermissions: z.array(z.number()), // Same as above, you can define more details if needed
});
type LoginUserResponse = z.infer<typeof LoginUserResponseSchema>;
const CalendarInterfaceSchema = z.object({
CalendarId: z.string(),
CalendarName: z.enum(["Oficial", "Pessoal"]),
CalendarRoleId: z.string(),
Id: z.number(),
OwnerUserId: z.unknown(), // You can define more specifically based on your requirements
});
type CalendarInterface = z.infer<typeof CalendarInterfaceSchema>;
const UserSessionSchema = z.object({
UserId: z.number(),
Authorization: z.string(),
Email: z.string().email(),
FullName: z.string(),
RoleDescription: z.string(),
RoleID: z.number(),
Password: z.string(),
RochetChatUserId: z.string(),
Profile: z.enum(['PR', 'MDGPR', 'Consultant', 'SGGPR', 'Unknown']),
LoginPreference: z.enum(['None', 'Password', 'Pin', null]).nullable(),
PIN: z.string(),
Inactivity: z.boolean(),
UrlBeforeInactivity: z.string(),
UserPermissions: z.unknown(), // Again, you can define it more explicitly if needed
UserPhoto: z.string(),
RefreshToken: z.string(),
});
type UserSession = z.infer<typeof UserSessionSchema>;
export class UserEntity {
wxUserId: number
wxFullName: string
wxeMail: string
role: string
roleId: number
userPhoto: string
adUserSID: string
authorization: string
refreshToken: string
permissions: number[]
Profile: 'PR' | 'MDGPR'| 'Consultant'| 'SGGPR'| 'Unknown'
constructor(input: any) {
Object.assign(this, input)
if (input) {
if (input?.user?.roleId == 100000014) {
this.Profile = 'PR'
} else if (input.user.roleId == 100000011) {
this.Profile = 'MDGPR'
} else if (input.user.roleId == 99999872) {
this.Profile = 'Consultant'
} else if (input.user.roleId == 99999886) {
this.Profile = 'SGGPR'
} else {
this.Profile = 'Unknown'
}
}
}
}
+19
View File
@@ -0,0 +1,19 @@
import { UserLoginOutputResponse } from "../repository/user-remote-repository";
import { UserLoginOutput } from "../use-case/user-login-use-case.service";
export class UserLoginMapper{
static toDomainData(input: UserLoginOutputResponse): UserLoginOutput {
return {
RefreshToken: input.data.refreshToken,
Authorization: input.data.authorization,
Email: input.data.user.wxeMail,
FullName: input.data.user.wxFullName,
RoleDescription: input.data.user.role,
RoleID: input.data.user.roleId,
UserId: input.data.user.wxUserId,
UserPermissions: input.data.permissions,
Profile: '',
UserPhoto: input.data.user?.userPhoto
}
}
}
@@ -0,0 +1,58 @@
import { HttpErrorResponse } from "@angular/common/http";
import { Result } from "neverthrow";
import { HttpResult } from "src/app/infra/http/type";
import { UserLoginInput } from "../use-case/user-login-use-case.service";
import { z } from "zod";
const UserRepositoryLoginParams = z.object({
Auth: z.string(),
ChannelId: z.number()
})
// Define the schema for the user object
const UserSchema = z.object({
wxUserId: z.number(),
wxFullName: z.string(),
wxeMail: z.string(),
role: z.string(),
roleId: z.number(),
userPhoto: z.string(),
adUserSID: z.string(),
});
// Define the schema for the main response object
const UserLoginOutputSchema = z.object({
user: UserSchema,
authorization: z.string(),
refreshToken: z.string(),
permissions: z.array(z.number()),
});
// Define the main schema for the response
const LoginUserResponseSchema = z.object({
success: z.boolean(),
message: z.nullable(z.string()), // Message can be null
data: UserLoginOutputSchema,
});
export type UserLoginOutputResponse = z.infer<typeof LoginUserResponseSchema>
const UserRefreshTokenInputSchema = z.object({
authorization: z.string(),
refreshToken: z.string(),
channelId: z.number()
})
export type UserRefreshTokenInputDTO = z.infer<typeof UserRefreshTokenInputSchema>
export type IUserRepositoryLoginParams = z.infer<typeof UserRepositoryLoginParams>
export abstract class IUserRemoteRepository {
abstract login(input: IUserRepositoryLoginParams): Promise<Result<HttpResult<UserLoginOutputResponse>, HttpErrorResponse>>
abstract logout(): Promise<Result<HttpResult<any>, HttpErrorResponse>>
abstract refreshToken(input:UserRefreshTokenInputDTO): Promise<Result<HttpResult<any>, HttpErrorResponse>>
}
@@ -0,0 +1,55 @@
import { Injectable } from '@angular/core';
import { IUserRemoteRepository } from '../repository/user-remote-repository';
import { XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
import { SessionStore } from 'src/app/store/session.service';
import { Router } from '@angular/router';
import { environment } from 'src/environments/environment';
import { NotificationsService } from 'src/app/services/notifications.service';
@Injectable({
providedIn: 'root'
})
export class UserLogOutUseCaseService {
constructor(
private userRemoteRepository: IUserRemoteRepository,
private router: Router,
private notificationService: NotificationsService,
) { }
@XTracerAsync({name:'UserLogOutUseCaseService', module:'user', bugPrint: true})
async execute() {
let logoutOut = false
let subscription = this.router.events.subscribe((val) => {
logoutOut = true
});
const result = await this.userRemoteRepository.logout()
SessionStore.setInativity(false)
SessionStore.setUrlBeforeInactivity(this.router.url);
logoutOut == false
if (environment.production) {
window.location.pathname = '/auth'
this.notificationService.DeletePostToken()
subscription.unsubscribe()
} else {
const pathBeforeGoOut = window.location.pathname
this.router.navigateByUrl('/auth', { replaceUrl: true });
this.notificationService.DeletePostToken()
setTimeout(() => {
if (logoutOut == false || pathBeforeGoOut == window.location.pathname) {
window.location.pathname = '/auth'
this.notificationService.DeletePostToken()
} else {
}
subscription.unsubscribe()
}, 500)
}
}
}
@@ -0,0 +1,104 @@
import { Injectable } from '@angular/core';
import { z, ZodError, ZodSchema } from 'zod';
import { IUserRemoteRepository } from '../repository/user-remote-repository';
import { XTracerAsync, TracingType } from 'src/app/services/monitoring/opentelemetry/tracer';
import { zodSafeValidation } from 'src/app/utils/zodValidation';
import { Platform } from '@ionic/angular';
import { AESEncrypt } from 'src/app/services/aesencrypt.service';
import { UserLoginMapper } from '../mapper/user-login';
import { UserSession } from 'src/app/models/user.model';
import { SessionStore } from 'src/app/store/session.service';
import { err, ok, Result } from 'neverthrow';
import { error } from '../../../services/Either/index';
const UserLoginInputSchema = z.object({
username: z.string(),
password: z.string()
})
export type UserLoginInput = z.infer<typeof UserLoginInputSchema>
// Define the schema for the main response object
const UserLoginOutputSchema = z.object({
UserId: z.number(),
Authorization: z.string(),
RefreshToken: z.string(),
Email: z.string().email(),
FullName: z.string(),
RoleDescription: z.string(),
RoleID: z.number(),
Profile: z.string(), // You can further define the Profile if you have more details
UserPermissions: z.array(z.number()), // Same as above, you can define more details if needed
UserPhoto: z.string().optional()
});
export type UserLoginOutput = z.infer<typeof UserLoginOutputSchema>
export enum LoginError {
userNotFound = 401,
}
@Injectable({
providedIn: 'root'
})
export class UserLoginUseCaseService {
constructor(
private userRemoteRepository: IUserRemoteRepository,
private aesencrypt: AESEncrypt,
private platform: Platform
) { }
@XTracerAsync({name:'UserLoginUseCaseService', module:'user', bugPrint: true})
async execute(input: UserLoginInput, tracing?: TracingType): Promise<Result<UserLoginOutput, LoginError | ZodError<UserLoginInput>>> {
const validation = zodSafeValidation<UserLoginInput>(UserLoginInputSchema, input)
if(validation.isOk()) {
let channelId;
if ( this.platform.is('desktop') || this.platform.is("mobileweb")) {
channelId = 2
} else {
channelId = 1
}
const auth = btoa(input.username + ':' + this.aesencrypt.encrypt(input.password, input.username))
const result = await this.userRemoteRepository.login({
Auth: auth,
ChannelId: channelId
})
if(result.isOk() && result.value.data.data) {
const data = UserLoginMapper.toDomainData(result.value.data);
const session: UserSession = Object.assign(SessionStore.user, data);
SessionStore.reset(session);
return ok(data)
} else if (result.isOk() && !result.value.data.data) {
return err(LoginError.userNotFound)
}
if(result.isErr() && result.error.status) {
return err(result.error.status as LoginError)
}
} else {
tracing.setAttribute('parameter error','true')
// Logger.error('failed to send message doe to invalid attachment', {
// zodErrorList: validation.error.errors,
// data: data
// })
return validation
}
}
}
@@ -0,0 +1,34 @@
import { Injectable } from '@angular/core';
import { z } from 'zod';
import { IUserRemoteRepository } from '../repository/user-remote-repository';
import { SessionStore } from 'src/app/store/session.service';
import { Platform } from '@ionic/angular';
import { XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
@Injectable({
providedIn: 'root'
})
export class UserRefreshTokenService {
constructor(
private userRemoteRepository: IUserRemoteRepository,
private platform: Platform
) { }
@XTracerAsync({name:'UserRefreshTokenService', module:'user', bugPrint: true})
async execute() {
let channelId;
if ( this.platform.is('desktop') || this.platform.is("mobileweb")){
channelId = 2
} else {
channelId = 1
}
return await this.userRemoteRepository.refreshToken({
authorization: SessionStore.user.Authorization,
refreshToken: SessionStore.user.RefreshToken,
channelId
})
}
}
+8 -8
View File
@@ -3,14 +3,13 @@ import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Rout
import { Observable } from 'rxjs';
import { PermissionService } from '../services/permission.service';
import { SessionStore } from '../store/session.service';
import { RouteService } from 'src/app/services/route.service'
import { FirstEnterService } from 'src/app/services/first-enter.service'
import { AlertController, Platform } from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
private router:Router,
public p: PermissionService,
@@ -68,12 +67,13 @@ export class AuthGuard implements CanActivate {
return false
}
} else if (pathname.startsWith('/home/events')) {
if(SessionStore?.user?.OwnerCalendars.length >= 1 || this.p.userPermission([this.p.permissionList.Gabinete.access])) {
return true
} else {
this.router.navigate(['/login']);
return false
}
// if(SessionStore?.user?.OwnerCalendars.length >= 1 || this.p.userPermission([this.p.permissionList.Gabinete.access])) {
// return true
// } else {
// this.router.navigate(['/login']);
// return false
// }
} else if (pathname == '/') {
this.router.navigate(['/login']);
return false
+4 -2
View File
@@ -29,7 +29,8 @@ export class InactivityGuard implements CanActivate {
if(this.p.userPermission(this.p.permissionList.Agenda.access) || this.p.userPermission(this.p.permissionList.Gabinete.access)) {
//When user has got access to Agenda but does not have their own calendar, goes to Agenda
if(this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore?.user?.OwnerCalendars.length == 0){
//if(this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore?.user?.OwnerCalendars.length == 0){
if(this.p.userPermission(this.p.permissionList.Agenda.access)){
this.router.navigate(['/home/agenda']);
}
else{
@@ -79,7 +80,8 @@ export class InactivityGuard implements CanActivate {
if((SessionStore?.user?.Inactivity)) {
if(this.p.userPermission(this.p.permissionList.Agenda.access) || this.p.userPermission(this.p.permissionList.Gabinete.access)){
//When user has got access to Agenda but does not have their own calendar, goes to Agenda
if(this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore?.user?.OwnerCalendars.length == 0) {
//if(this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore?.user?.OwnerCalendars.length == 0) {
if(this.p.userPermission(this.p.permissionList.Agenda.access)) {
this.router.navigate(['/home/agenda']);
}
else{
+4 -2
View File
@@ -6,8 +6,10 @@
<app-header ></app-header>
</ion-header>
<ion-tab-bar id="bottom-navigation" class="dnone" *ngIf="p.userPermissionCount([permissionList.Agenda.access, permissionList.Gabinete.access, permissionList.Actions.access, permissionList.Chat.access]) >= 2 || (p.userPermission([permissionList.Agenda.access]) && SessionStore.user.OwnerCalendars.length != 0) || p.userPermission([permissionList.Gabinete.access])" class="bottoms" slot="bottom">
<ion-tab-button *ngIf="SessionStore.user.OwnerCalendars.length >= 1 || p.userPermission([permissionList.Gabinete.access])" (click)="goto('/home/events')" tab="events" [class.active]="ActiveTabService.pages.home">
<!-- <ion-tab-bar id="bottom-navigation" class="dnone" *ngIf="p.userPermissionCount([permissionList.Agenda.access, permissionList.Gabinete.access, permissionList.Actions.access, permissionList.Chat.access]) >= 2 || (p.userPermission([permissionList.Agenda.access]) && SessionStore.user.OwnerCalendars.length != 0) || p.userPermission([permissionList.Gabinete.access])" class="bottoms" slot="bottom">
<ion-tab-button *ngIf="SessionStore.user.OwnerCalendars.length >= 1 || p.userPermission([permissionList.Gabinete.access])" (click)="goto('/home/events')" tab="events" [class.active]="ActiveTabService.pages.home"> -->
<ion-tab-bar id="bottom-navigation" class="dnone" *ngIf="p.userPermissionCount([permissionList.Agenda.access, permissionList.Gabinete.access, permissionList.Actions.access, permissionList.Chat.access]) >= 2 || (p.userPermission([permissionList.Agenda.access])) || p.userPermission([permissionList.Gabinete.access])" class="bottoms" slot="bottom">
<ion-tab-button *ngIf="p.userPermission([permissionList.Gabinete.access])" (click)="goto('/home/events')" tab="events" [class.active]="ActiveTabService.pages.home">
<!-- <ion-icon name="home"></ion-icon> -->
<ion-icon *ngIf="!ActiveTabService.pages.home" class="font-30-em" src="assets/images/icons-nav-home.svg"></ion-icon>
<ion-icon *ngIf="ActiveTabService.pages.home" class="font-30-em" src="assets/images/nav-hover/icons-nav-home-active.svg"></ion-icon>
+3 -3
View File
@@ -229,9 +229,9 @@ export class HomePage implements OnInit {
throw (SessionStore.user.FullName + 'cant have MD and PR authorization at same time');
}
if (this.p.userPermission([this.p.permissionList.Chat.access]) && !SessionStore.user?.ChatData?.data) {
throw ('Chat temporarily unavailable for ' + SessionStore.user.FullName + '. No ChatData');
}
// if (this.p.userPermission([this.p.permissionList.Chat.access]) && !SessionStore.user?.ChatData?.data) {
// throw ('Chat temporarily unavailable for ' + SessionStore.user.FullName + '. No ChatData');
// }
// if (this.p.userPermission([this.p.permissionList.Agenda.access]) && !this.eventService.hasAnyCalendar) {
// // throw ('User ' + SessionStore.user.FullName + 'has No calendar');
-5
View File
@@ -7,12 +7,7 @@ const routes: Routes = [
{
path: '',
component: IndexPage,
/* canActivate: [IndexGuard], */
children: [
/*{
path: '',
loadChildren: ()=> import('../pages/welcome/welcome.module').then(m => m.WelcomePageModule)
}, */
{
path: '',
loadChildren: ()=> import('../pages/login/login.module').then(m => m.LoginPageModule),
@@ -1,20 +1,20 @@
import { Dexie } from 'Dexie';
import { DexieMessageTable, messageTableColumn, MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
import { DexieMessageTable, messageTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/message';
import { DexieMembersTableSchema, MemberTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/members';
import { DexieRoomsTable, RoomTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/room';
import { DexieTypingsTable, TypingTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/typing';
import { MessageEntity } from 'src/app/core/chat/entity/message';
import { AttachmentTableColumn, DexieAttachmentsTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/attachment';
import { DexieDistributionTable, DistributionTable, DistributionTableColumn } from './schema/destribution';
import { DexieDistributionTable, DistributionTableColumn } from './schema/destribution';
import { BoldTableColumn, DexieBoldTable } from './schema/bold';
import { DexieUserPhotoTable, UserPhotoTable, UserPhotoTableColumn } from './schema/user-foto';
// import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
// import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
import { DexieUserPhotoTable, UserPhotoTableColumn } from './schema/user-foto';
import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
// Database declaration (move this to its own module also)
export const chatDatabase = new Dexie('chat-database-v3',{
export const chatDatabase = new Dexie('chat-database-v4',{
//indexedDB: new FDBFactory,
//IDBKeyRange: FDBKeyRange, // Mocking IDBKeyRange
}) as Dexie & {
+1 -1
View File
@@ -48,7 +48,7 @@ export class HttpService {
const httpOptions = {
params: httpParams,
headers: options?.headers || new HttpHeaders(),
headers: options?.headers as any || new HttpHeaders(),
responseType: options?.responseType || 'json' as any,
};
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { meter, RequestCounter } from '../services/monitoring/opentelemetry/matrix';
import { meter, RequestCounter } from '../../../services/monitoring/opentelemetry/matrix';
@Injectable()
@@ -10,10 +10,14 @@ import {
} from "@angular/common/http";
import { Observable, throwError, BehaviorSubject, of } from "rxjs";
import { catchError, filter, take, switchMap, tap } from "rxjs/operators";
import { SessionStore } from '../store/session.service';
import { SessionStore } from '../../../store/session.service';
import { environment } from "src/environments/environment";
import { Router } from "@angular/router";
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { Platform } from '@ionic/angular';
import { UserLoginOutputResponse } from "../../../core/user/repository/user-remote-repository";
import { UserLoginMapper } from "../../../core/user/mapper/user-login";
import { UserSession } from "../../../models/user.model";
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
@@ -24,7 +28,11 @@ export class TokenInterceptor implements HttpInterceptor {
private excludedDomains = [ 'Login', environment.apiChatUrl, 'http://localhost:8019']; // Add the domains you want to exclude
constructor(private http: HttpClient, private router: Router,private httpErrorHandle: HttpErrorHandle,) { }
constructor(
private http: HttpClient,
private router: Router,
private httpErrorHandle: HttpErrorHandle,
private platform: Platform) { }
intercept(
@@ -44,7 +52,11 @@ export class TokenInterceptor implements HttpInterceptor {
catchError((error) => {
console.log('interceptor ',error)
if (error instanceof HttpErrorResponse && error.status === 401) {
if(error.url.includes('/Users/RefreshToken') && error.status === 401) {
console.log("refresh token error11",error)
return throwError(error);
}
else if (error instanceof HttpErrorResponse && error.status === 401) {
return this.handle401Error(request, next);
} else if (error.url.includes('https://gdapi-dev.dyndns.info/stage/api/v2') && error.status === 0){
return this.handle401Error(request, next);
@@ -78,10 +90,10 @@ export class TokenInterceptor implements HttpInterceptor {
this.refreshTokenSubject.next(null);
return this.refreshToken().pipe(
switchMap((token: any) => {
switchMap((data: UserLoginOutputResponse) => {
this.isRefreshing = false;
this.refreshTokenSubject.next(token.Authorization);
return next.handle(this.addToken(request, token.Authorization));
this.refreshTokenSubject.next(data?.data?.authorization);
return next.handle(this.addToken(request, data?.data?.authorization));
})
);
} else {
@@ -99,23 +111,33 @@ export class TokenInterceptor implements HttpInterceptor {
//this method refresh token is declared here temporary beacouse a circular error
refreshToken() {
let channelId;
if ( this.platform.is('desktop') || this.platform.is("mobileweb")){
channelId = 2
} else {
channelId = 1
}
return this.http
.put<any>(environment.apiURL + "UserAuthentication/RefreshToken", {
.post<UserLoginOutputResponse>('https://gdapi-dev.dyndns.info/stage/api/v2/Users/RefreshToken', {
authorization: SessionStore.user.Authorization,
refreshToken: SessionStore.user.RefreshToken,
channelId
},)
.pipe(
tap((tokens) => {
console.log(tokens)
SessionStore.user.Authorization = tokens.Authorization;
SessionStore.user.RefreshToken = tokens.refreshToken;
SessionStore.save();
tap((data) => {
SessionStore.user.Authorization = data.data.authorization;
SessionStore.user.RefreshToken = data.data.refreshToken;
//const userData = UserLoginMapper.toDomainData(data)
//const session: UserSession = Object.assign(SessionStore.user, userData)
//SessionStore.reset(session)ta
}),
catchError((error) => {
console.log(error)
SessionStore.user.Authorization = SessionStore.user.Authorization;
SessionStore.user.RefreshToken = SessionStore.user.RefreshToken;
console.log("refresh token error",error)
// SessionStore.user.Authorization = SessionStore.user.Authorization;
// SessionStore.user.RefreshToken = SessionStore.user.RefreshToken;
SessionStore.setInativity(false)
/* SessionStore.setUrlBeforeInactivity(this.router.url); */
@@ -1,179 +0,0 @@
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent,
HttpErrorResponse,
HTTP_INTERCEPTORS,
HttpHeaders,
} from '@angular/common/http';
import { Observable, throwError, BehaviorSubject } from 'rxjs';
import { catchError, switchMap, filter, take } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { SessionStore } from '../store/session.service';
import { environment } from "src/environments/environment";
import { PermissionService } from '../services/permission.service';
import { NetworkServiceService, ConnectionStatus } from 'src/app/services/network-service.service';
// import { RochetChatConnectorService } from 'src/app/services/chat/rochet-chat-connector.service';
@Injectable()
export class ChatTokenInterceptor implements HttpInterceptor {
private isRefreshing = false;
headers: HttpHeaders;
options: any;
private refreshChatTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(
null
);
private excludedDomains = ['Login',environment.apiURL, 'http://localhost:8019'];// Add other domains as needed
constructor(private http: HttpClient, private router: Router, private p: PermissionService, private NetworkServiceService: NetworkServiceService) { }
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (this.shouldExcludeDomain(request)) {
return next.handle(request);
}
if (SessionStore.user.Authorization) {
request = this.addToken(request, SessionStore.user.Authorization);
}
return next.handle(request).pipe(
catchError((error) => {
if (error instanceof HttpErrorResponse && error.status === 401) {
return this.handle401Error(request, next);
} else {
return throwError(error);
}
})
);
}
private shouldExcludeDomain(request: HttpRequest<any>): boolean {
const url = request.url.toLowerCase();
return this.excludedDomains.some((domain) => url.includes(domain.toLowerCase()));
}
private handle401Error(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshChatTokenSubject.next(null);
return this.refreshToken().pipe(
switchMap((token: any) => {
this.isRefreshing = false;
let data = {
status: token['status'],
data: {
userId: token['data'].userId,
authToken: token['data'].authToken
}
}
SessionStore.user.ChatData = data
SessionStore.save()
/* this.setheader() */
this.refreshChatTokenSubject.next(token.Authorization);
return next.handle(this.addToken(request, token.Authorization));
})
);
} else {
return this.refreshChatTokenSubject.pipe(
filter((token) => token != null),
take(1),
switchMap((jwt) => {
return next.handle(this.addToken(request, jwt));
})
);
}
}
private addToken(request: HttpRequest<any>, token: string) {
let headers = new HttpHeaders();
try {
headers = headers.set('X-User-Id', SessionStore?.user?.ChatData?.data?.userId);
headers = headers.set('X-Auth-Token', SessionStore?.user?.ChatData?.data.authToken);
return request.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
...headers.keys().reduce((acc, key) => ({ ...acc, [key]: headers.get(key) }), {}),
},
})
} catch (error) {
return request.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
})
}
}
/* private addToken(request: HttpRequest<any>, token: string) {
return request.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
});
} */
private refreshToken(): Observable<any> {
return this.http
.get<any>(environment.apiURL + 'UserAuthentication/RegenereChatToken', {
/* refreshToken: SessionStore.user.RefreshToken, */
})
.pipe(
catchError((error) => {
// Handle token refresh failure
console.log('ChatToken refresh failed:', error);
return throwError(error);
})
);
}
setheader() {
try {
if (this.p.userPermission(this.p.permissionList.Chat.access) && SessionStore.user.ChatData) {
this.headers = new HttpHeaders();;
if (this.p.userPermission(this.p.permissionList.Chat.access)) {
//
this.headers = this.headers.set('X-User-Id', SessionStore.user.ChatData.data.userId);
this.headers = this.headers.set('X-Auth-Token', SessionStore.user.ChatData.data.authToken);
this.options = {
headers: this.headers,
};
}
}
} catch (error) {
}
}
}
export const chatTokenInterceptor = {
provide: HTTP_INTERCEPTORS,
useClass: ChatTokenInterceptor,
multi: true
};
@@ -9,7 +9,7 @@ import { DiscartExpedientModalPage } from 'src/app/pages/gabinete-digital/discar
import { ExpedienteDetailPage } from 'src/app/pages/gabinete-digital/expediente/expediente-detail/expediente-detail.page';
import { SearchList } from 'src/app/models/search-document';
import { SearchPage } from 'src/app/pages/search/search.page';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { AttendeesPageModal } from 'src/app/pages/events/attendees/attendees.page';
import { ToastService } from 'src/app/services/toast.service';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@@ -85,7 +85,7 @@ export class CreateProcessPage implements OnInit {
documents: SearchList[] = [];
loggeduser: LoginUserRespose;
loggeduser: UserSession;
toppings = new FormControl();
@@ -311,7 +311,8 @@ export class CreateProcessPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
try {
@@ -337,7 +338,8 @@ export class CreateProcessPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: { a: 1}
}
try {
@@ -362,7 +364,8 @@ export class CreateProcessPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
try {
@@ -395,7 +398,8 @@ export class CreateProcessPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
try {
@@ -425,7 +429,8 @@ export class CreateProcessPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
/* if (this.postData.DispatchFolder.Message) { */
@@ -456,7 +461,8 @@ export class CreateProcessPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
try {
@@ -488,7 +494,8 @@ export class CreateProcessPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
try {
@@ -5,7 +5,7 @@ import { Event } from 'src/app/models/event.model'
import { EventPerson } from 'src/app/models/eventperson.model';
import { SearchPage } from 'src/app/pages/search/search.page';
import { SearchDocumentDetails, SearchFolderDetails, SearchList } from 'src/app/models/search-document';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { AuthService } from 'src/app/services/auth.service';
import { AttendeesPageModal } from 'src/app/pages/events/attendees/attendees.page';
import { ToastService } from 'src/app/services/toast.service';
@@ -92,7 +92,7 @@ export class DocumentSetUpMeetingPage implements OnInit {
formLocationSatus: boolean = false;
showAttendees = false;
loggeduser: LoginUserRespose;
loggeduser: UserSession;
emptyTextDescription = "Selecionar intervenientes";
document: SearchFolderDetails | SearchDocumentDetails | any;
@@ -125,7 +125,7 @@
</div>
</div>
<!--<div class="profile-title d-flex justify-space-between align-center width-100">
<div class="profile-title d-flex justify-space-between align-center width-100">
<div class="d-flex align-center">
<div>Tema</div>
</div>
@@ -146,7 +146,7 @@
</div>
</div>
</div> -->
</div>
</div>
+4 -1
View File
@@ -7,13 +7,16 @@ import { IonicModule } from '@ionic/angular';
import { ProfilePageRoutingModule } from './profile-routing.module';
import { ProfilePage } from './profile.page';
import { UserModule } from 'src/app/module/user/user.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ProfilePageRoutingModule
ProfilePageRoutingModule,
//
UserModule
],
declarations: [ProfilePage]
})
+6 -2
View File
@@ -85,19 +85,23 @@
<div class="line"></div>
<ion-progress-bar type="indeterminate" *ngIf="isloading"></ion-progress-bar>
<!-- <ion-label (click)="asyncNotification()" *ngIf="NotificationHolderService.notificationList">{{notificationStatus}}</ion-label> -->
<button *ngIf="(notificationList$ | async) as notificationList" style="background: transparent; padding-top: 5px; float: right;" (click)="deleteAllNotification()" class="pointer cursor-pointer">
<ion-icon *ngIf="notificationList.length >= 1" (click)="deleteAllNotification()" style="height: 25px;width: 25px;float: right;" class="delete" src='assets/images/theme/gov/icons-delete.svg'></ion-icon>
</button>
</div>
</ion-header>
<ion-content class=" bg-blue">
<div class="d-flex flex-column height-100 overflow-y-auto">
<div class="notifications-content height-100">
<ion-list *ngIf="(notificationList$ | async) as notificationList">
<div class=" cursor-pointer ion-no-padding ion-no-margin" lines="none"
*ngFor="let item of notificationList; let i = index">
<div *ngIf="item.status==false " class="item" (click)="notificatinsRoutes(item.index, item)">
<div class="item" (click)="notificatinsRoutes(item.index, item)">
<div *ngIf="objectRead[item.notificationId] != true" class="item-conten1 item-conten-{{item.service}}-{{item.typeAgenda}}-{{item.role}} llll" >
<div class="notification-item">
+1
View File
@@ -77,6 +77,7 @@
}
.profile-content {
padding: 20px 20px;
padding-bottom: 5px;
//color: var(--profile-text-color) !important;
}
+13 -26
View File
@@ -4,7 +4,6 @@ import { AnimationController, ModalController } from '@ionic/angular';
import { AuthService } from 'src/app/services/auth.service';
import { EditProfilePage } from './edit-profile/edit-profile.page';
import { StorageService } from '../../services/storage.service';
import { NotificationsService } from '../../services/notifications.service';
import { SessionStore } from 'src/app/store/session.service';
import { ThemeService } from 'src/app/services/theme.service'
import { environment } from 'src/environments/environment';
@@ -19,6 +18,8 @@ import { NotificationTable } from 'src/app/module/notification/data/infra/db/not
import { isHttpError } from 'src/app/services/http.service';
import { UserRepositoryService } from 'src/app/module/user/data/user-repository.service';
import { UserProfilePicture } from 'src/app/module/user/data/datasource/user-local-repository.service';
import { UserService } from 'src/app/module/user/domain/user.service'
import { NotificationService } from 'src/app/module/notification/domain/notification.service'
@Component({
selector: 'app-profile',
@@ -61,7 +62,7 @@ export class ProfilePage implements OnInit {
private router: Router,
private zone: NgZone,
public ThemeService: ThemeService,
private notificationService: NotificationsService,
private NotificationService: NotificationService,
private processesService: ProcessesService,
private storageService: StorageService,
public NotificationHolderService: NotificationHolderService,
@@ -69,7 +70,8 @@ export class ProfilePage implements OnInit {
private agendaDataRepository: AgendaDataRepositoryService,
private toastService: ToastService,
private notificationRepositoryService: NotificationRepositoryService,
private UserRepositoryService: UserRepositoryService
private UserRepositoryService: UserRepositoryService,
private UserService:UserService,
) {
this.profilePictureSubject = this.UserRepositoryService.getProfilePictureLive() as any
@@ -350,29 +352,7 @@ export class ProfilePage implements OnInit {
}
logout() {
this.authservice.logoutUser();
SessionStore.setInativity(false)
SessionStore.setUrlBeforeInactivity(this.router.url);
this.logoutOut == false
if (environment.production) {
window.location.pathname = '/auth'
this.notificationService.DeletePostToken()
} else {
const pathBeforeGoOut = window.location.pathname
this.router.navigateByUrl('/auth', { replaceUrl: true });
this.notificationService.DeletePostToken()
setTimeout(() => {
if (this.logoutOut == false || pathBeforeGoOut == window.location.pathname) {
window.location.pathname = '/auth'
this.notificationService.DeletePostToken()
} else {
}
}, 500)
}
this.UserService.logout();
}
async editProfile() {
@@ -436,4 +416,11 @@ export class ProfilePage implements OnInit {
this.deleteNotification(item);
}
async deleteAllNotification() {
console.log('nice job')
await this.NotificationService.deleteAllNotificationByUserId()
this.notificationRepositoryService.init()
}
}
+1
View File
@@ -15,4 +15,5 @@ export class Despacho{
SourceId: string
}[],
}
dataFields: Object
}
@@ -6,15 +6,18 @@ export class AgendaPermission{
constructor() {
if(SessionStore.exist) {
for (let calendar of SessionStore?.user?.OwnerCalendars) {
this.hasOwnCalendar = true
}
// for (let calendar of SessionStore?.user?.OwnerCalendars) {
// this.hasOwnCalendar = true
// }
for (let sharedCalendar of SessionStore?.user?.SharedCalendars) {
// for (let sharedCalendar of SessionStore?.user?.SharedCalendars) {
// this.hasSharedCalendar = true
// }
this.hasOwnCalendar = true
this.hasSharedCalendar = true
}
}
}
get access () {
return 530
-67
View File
@@ -6,41 +6,6 @@ export class UserForm {
}
export class LoginUserRespose {
BasicAuthKey: string;
UserId: number;
Authorization: string;
ChatData: {
status: string,
data: {
userId: string,
authToken: string
}
}
Email: string
FullName: string
OwnerCalendars: {
CalendarId: string
CalendarName: "Oficial" | "Pessoal";
CalendarRoleId: string;
Id: number;
}[]
RoleDescription: string
RoleID: number
SharedCalendars: {
CalendarId: string
CalendarName: "Oficial" | "Pessoal";
CalendarRoleId: string;
Id: number;
OwnerUserId: string;
TypeShare: number;
}[]
UserName: string
Profile: any;
UserPermissions: any;
}
export class calendarInterface {
CalendarId: string
CalendarName: "Oficial" | "Pessoal";
@@ -50,44 +15,12 @@ export class calendarInterface {
}
export class UserSession {
BasicAuthKey: string;
UserId: number;
Authorization: string;
ChatData: {
status: string,
data: {
userId: string,
authToken: string
}
}
Email: string
FullName: string
ManagerName: string
OwnerCalendars: {
CalendarId: string
CalendarName: "Oficial" | "Pessoal";
CalendarRoleId: string;
Id: number;
OwnerUserId: any
}[]
RoleDescription: string
RoleID: number
SharedCalendars: {
CalendarId: string
CalendarName: "Oficial" | "Pessoal";
/**
* @description User Role Id
*/
CalendarRoleId: string;
Id: number;
OwnerUserId: string;
TypeShare: number;
/**
* @description deprecated
*/
CalendarToken: string;
}[]
UserName: string
Password: string
RochetChatUserId: string
Profile: 'PR' | 'MDGPR' | 'Consultant' | 'SGGPR' | 'Unknown' ;
@@ -189,16 +189,16 @@ export class AgendaDataRepositoryService {
let body;
if(typeof eventData?.Body == 'object') {
body = eventData?.Body?.Text
} else {
body = eventData?.Body
body = eventData.Body.Text
} else if (eventData?.Body) {
body = eventData.Body
}
let eventInput = {
userId: calendar.wxUserId,
ownerType: this.utils.selectedCalendarOwner(calendar.role),
subject: eventData.Subject,
body: eventData?.Body?.Text,
body: body,
location: eventData.Location,
startDate: this.utils.addOneHourToIsoString(eventData.StartDate),
endDate: this.utils.addOneHourToIsoString(eventData.EndDate),
@@ -6,10 +6,10 @@ import { SessionStore } from 'src/app/store/session.service';
import { SignalRService } from 'src/app/infra/socket/signalR/signal-r.service';
import { v4 as uuidv4 } from 'uuid'
import { CreateRoomInputDTO, RoomOutPutDTO } from '../../../../../core/chat/usecase/room/room-create-use-case.service';
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
import { IRoomRemoteRepository, ISearchRoom } from 'src/app/core/chat/repository/room/room-remote-repository';
import { RoomByIdOutputDTO } from 'src/app/core/chat/usecase/room/room-get-by-id-use-case.service';
import { RoomUpdateInputDTO, RoomUpdateOutputDTO } from 'src/app/core/chat/usecase/room/room-update-by-id-use-case.service';
import { RoomListOutPutDTO } from '../../../../../core/chat/usecase/room/room-get-list-use-case.service';
import { RoomListItemOutPutDTO, RoomListItemSchema, RoomListOutPutDTO } from '../../../../../core/chat/usecase/room/room-get-list-use-case.service';
import { z } from 'zod';
import { HttpAdapter } from 'src/app/infra/http/adapter';
import { AddMemberToRoomInputDTO } from 'src/app/core/chat/usecase/member/member-add-use-case.service';
@@ -54,6 +54,13 @@ export class RoomRemoteDataSourceService implements IRoomRemoteRepository {
return result.map((e)=> e.data)
}
async search(input: string): Promise<Result<RoomListItemOutPutDTO[], any>> {
const result = await this.Http.get<ISearchRoom>(`${this.baseUrl}/search?value=${input}`);
return result.map((e)=> ( e.data.data.rooms.map(j => ({ chatRoom: j, joinAt: ''})) ))
}
//@ValidateSchema(RoomUpdateInputDTOSchema)
//@APIReturn(RoomByIdOutputDTOSchema,'update/Room/${id}')
async updateRoom(data: RoomUpdateInputDTO): Promise<DataSourceReturn<RoomUpdateOutputDTO>> {
@@ -21,7 +21,7 @@ export function NotificationListChanges(
const localItem = localMap.get(id);
if (!localItem) {
changes.insert.push(serverItem);
} else if (localItem.status !== serverItem.status) {
} else if (localItem.viewDate !== serverItem.viewDate) {
changes.update.push(serverItem);
}
}
@@ -122,7 +122,7 @@ export class LocalNotificationService {
return from(liveQuery( () => {
return NotificationDataSource.notification.orderBy('createdAt').reverse().toArray()
.then(notifications => {
return notifications.filter(notification => notification.status === false)
return notifications.filter(notification => notification.viewDate == null)
})
}))
}
@@ -132,7 +132,7 @@ export class LocalNotificationService {
return NotificationDataSource.notification
.toArray()
.then(notifications => {
return notifications.filter(notification => notification.status === false).length
return notifications.filter(notification => notification.viewDate == null).length
})
}))
}
@@ -22,8 +22,12 @@ export class RemoteNotificationService {
}
async notificationStatus(id: string) {
async notificationStatus(id: number) {
return await this.httpService.patch<NotificationOutputDTO>(`${this.baseUrl}/Notifications/${id}/status`);
}
async notificationDeleteAll(userId: any) {
return await this.httpService.delete<NotificationOutputDTO>(`${this.baseUrl}/Notifications/${userId}`);
}
}
@@ -8,7 +8,7 @@ export const NotificationOutputDTOSchema = z.object({
total: z.number(),
result: z.array(
z.object({
id: z.string(),
id: z.number(),
service: z.string(),
title: z.string(),
body: z.string(),
@@ -17,7 +17,6 @@ export const NotificationOutputDTOSchema = z.object({
folderId: z.string().nullable(),
createdAt: z.string(),
viewDate: z.string().nullable(),
status: z.boolean(),
startDate: z.string().nullable(),
endDate: z.string().nullable(),
bodyEvent: z.string().nullable(),
@@ -2,16 +2,16 @@ import { Dexie, EntityTable, liveQuery } from 'Dexie';
import { z } from 'zod';
export const NotificationTableSchema = z.object({
notificationId: z.string().nullable(),
notificationId: z.number().nullable(),
title: z.string().optional().nullable(),
service: z.string().nullable(),
object: z.string().optional().nullable(),
idObject: z.string().nullable(),
viewDate: z.string().nullable(),
folderId: z.string().optional().nullable(),
dateInit: z.string().optional().nullable(),
dateEnd: z.string().optional().nullable(),
location: z.string().optional().nullable(),
status: z.boolean().optional(),
notificationBody: z.any().optional()
})
export type NotificationTable = z.infer<typeof NotificationTableSchema>
@@ -1,16 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { NotificationRepositoryService } from './notification-repository.service';
describe('NotificationRepositoryService', () => {
let service: NotificationRepositoryService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(NotificationRepositoryService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -83,7 +83,7 @@ export class NotificationRepositoryService {
async notificationStatus(item: NotificationTable) {
await this.RemoteNotificationService.notificationStatus(item.notificationId)
item.status = true
item.viewDate = new Date().toUTCString()
this.LocalNotificationService.updateNotification(item)
this
this.init()
@@ -93,14 +93,14 @@ export class NotificationRepositoryService {
async RemoveNotificationStatus(item: NotificationTable) {
await this.RemoteNotificationService.notificationStatus(item.notificationId)
item.status = true
item.viewDate = new Date().toUTCString()
this.LocalNotificationService.updateNotification(item)
this.init()
return
}
async localNotificationStatus(item: NotificationTable) {
item.status = true
item.viewDate = new Date().toUTCString()
this.LocalNotificationService.updateNotification(item)
this.init()
return
@@ -14,9 +14,9 @@ export function NotificationListMapper(NotificationOutputDTO: NotificationOutput
dateInit: e.startDate,
dateEnd: e.endDate,
createdAt: e.createdAt,
status: e.status,
location: e.location,
notificationBody: e.body
notificationBody: e.body,
viewDate: e.viewDate
}
))
}
@@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { INotificationDeleteAllByUserId, NotificationDeleteAllServiceUseCase } from 'src/app/core/notification/use-case/notification-delete-all-use-case.service'
@Injectable({
providedIn: 'root'
})
export class NotificationService {
constructor(
private NotificationDeleteAllServiceUseCase: NotificationDeleteAllServiceUseCase
) { }
deleteAllNotificationByUserId() {
return this.NotificationDeleteAllServiceUseCase.execute()
}
}
@@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { HttpModule } from 'src/app/infra/http/http.module';
@NgModule({
imports: [HttpModule],
providers: [],
declarations: [],
schemas: [],
entryComponents: []
})
export class NotificationModule {
constructor() {}
}
@@ -4,16 +4,40 @@ import { environment } from 'src/environments/environment';
import { IProfilePictureInputDTO } from '../dto/profilePictureInputDTO';
import { HttpHeaders } from '@angular/common/http';
import { TracingType } from 'src/app/services/monitoring/opentelemetry/tracer';
import { HttpAdapter } from 'src/app/infra/http/adapter';
import { IUserRepositoryLoginParams, UserRefreshTokenInputDTO } from 'src/app/core/user/repository/user-remote-repository';
import { UserLoginOutput } from 'src/app/core/user/use-case/user-login-use-case.service';
import { SessionStore } from 'src/app/store/session.service';
@Injectable({
providedIn: 'root'
})
export class UserRemoteRepositoryService {
private baseUrl = 'https://gdapi-dev.dyndns.info/stage/api/v2'; // Your base URL
constructor(
private httpService: HttpService
private httpService: HttpService,
private http: HttpAdapter,
) { }
// @APIReturn(MessageOutPutDTOSchema, 'get/Messages')
async login(input: IUserRepositoryLoginParams) {
return await this.http.post<UserLoginOutput>(`${this.baseUrl}/Users/login`, input)
}
// @APIReturn(MessageOutPutDTOSchema, 'get/Messages')
async logout() {
return await this.http.post<UserLoginOutput>(`${this.baseUrl}/Users/${SessionStore.user.UserId}/logout`, {})
}
async refreshToken(input: UserRefreshTokenInputDTO) {
return await this.http.post<UserLoginOutput>(`${this.baseUrl}/Users/RefreshToken`, input)
}
getUserProfilePhoto(guid: string, tracing?: TracingType) {
const geturl = environment.apiURL + 'UserAuthentication/GetPhoto';
@@ -0,0 +1,135 @@
import { Injectable } from '@angular/core';
import { UserEntity } from 'src/app/core/user/entity/userEntity';
import { SHA1 } from 'crypto-js'
import { localstoreService } from 'src/app/store/localstore.service';
import { Preference } from 'src/app/core/user/entity/preference';
@Injectable({
providedIn: 'root'
})
export class SessionService {
user?:UserEntity
preference = new Preference()
forceToLoginWithForceToLogInWithPassword = false
private keyName: string;
constructor() {
if(this.exist) {
this.keyName = (SHA1("")).toString()
let restore: any = this.getDataFromLocalStorage()
if(restore?.user) {
this.user = new UserEntity(restore.user)
}
if(this.preference.LoginPreference == 'Pin') {
this.preference.Inactivity = false
}
}
}
getDataFromLocalStorage() {
return localstoreService.get(this.keyName, {}).user as UserEntity
}
get exist() {
let restore = localstoreService.get(this.keyName, {})
let user: UserEntity = restore.user
if(user) {
if(user.Profile) {
console.log('exist')
return true
}
}
console.log('exist not', restore)
return false
}
setLoginPreference(loginPreference: 'None' | 'Password' | 'Pin' | null) {
this.preference.LoginPreference = loginPreference
this.save()
}
setPin(pin: string) {
this.preference.PIN = SHA1(pin).toString()
this.save()
}
validatePin(pin: string) {
return this.preference.PIN == SHA1(pin).toString()
}
needToValidateUser() {
return this.preference.Inactivity
}
isUserActive() {
return this.preference.Inactivity
}
setInativity(value: boolean) {
this.preference.Inactivity = value
this.preference.UrlBeforeInactivity = ''
this.save()
}
setUrlBeforeInactivity(pathname: string) {
this.preference.UrlBeforeInactivity = pathname
this.save()
}
get hasPin() {
if(!this.preference.PIN) {
return false
}
return this.preference.PIN.length >= 2
}
reset(user) {
console.log('reset')
console.log('user', user)
this.user = user
this.setInativity(true)
this.save()
}
delete() {
console.log('edeletet')
localstoreService.delete(this.keyName)
this.preference = new Preference()
delete this.user
}
save() {
console.log('save')
localstoreService.set(this.keyName, {
user: this.user,
preference: this.preference
})
}
get getInitials() {
let names = this.user.wxFullName.split(' ') || ' ',
initials = names[0].substring(0, 1).toUpperCase();
if (names.length > 1) {
initials += names[names.length - 1].substring(0, 1).toUpperCase();
}
return initials;
}
}
export const SessionStore = new SessionService()
@@ -0,0 +1,38 @@
import { Injectable } from '@angular/core';
import { IUserRemoteRepository } from 'src/app/core/user/repository/user-remote-repository';
import { UserLoginInput, UserLoginUseCaseService } from 'src/app/core/user/use-case/user-login-use-case.service';
import { UserLogOutUseCaseService } from 'src/app/core/user/use-case/user-log-out-use-case.service';
import { SessionStore } from './service/session.service'
import { UserEntity } from 'src/app/core/user/entity/userEntity';
import { UserRefreshTokenService } from 'src/app/core/user/use-case/user-refresh-token.service';
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(
private userLoginUseCaseService: UserLoginUseCaseService,
private userLogOutUseCaseService: UserLogOutUseCaseService,
private userRefreshTokenService: UserRefreshTokenService
) { }
async login(input: UserLoginInput) {
const result = await this.userLoginUseCaseService.execute(input)
if(result.isOk()) {
// SessionStore.reset(new UserEntity({...result.value, ...result.value.user}))
}
return result
}
async logout() {
return await this.userLogOutUseCaseService.execute()
}
refreshToken() {
return this.userRefreshTokenService.execute()
}
}
+33
View File
@@ -0,0 +1,33 @@
import { NgModule } from '@angular/core';
import { HttpModule } from 'src/app/infra/http/http.module';
import { IUserRemoteRepository } from 'src/app/core/user/repository/user-remote-repository';
import { UserRemoteRepositoryService } from './data/datasource/user-remote-repository.service';
import { UserService } from './domain/user.service'
import { UserLoginUseCaseService } from 'src/app/core/user/use-case/user-login-use-case.service';
import { UserLogOutUseCaseService } from 'src/app/core/user/use-case/user-log-out-use-case.service';
import { UserRefreshTokenService } from 'src/app/core/user/use-case/user-refresh-token.service';
@NgModule({
imports: [HttpModule],
providers: [
{
provide: IUserRemoteRepository,
useClass: UserRemoteRepositoryService, // or MockDataService
},
// domain service
UserService,
// use case
UserLoginUseCaseService,
UserLogOutUseCaseService,
UserRefreshTokenService
],
declarations: [],
schemas: [],
entryComponents: [
],
})
export class UserModule {
constructor() {}
}
@@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { EventPerson } from 'src/app/models/eventperson.model';
import { ModalController, NavParams } from '@ionic/angular';
import { ThemeService } from 'src/app/services/theme.service'
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { SessionStore } from 'src/app/store/session.service';
import { Router } from '@angular/router';
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
@@ -25,7 +25,7 @@ export class AttendeesPageModal implements OnInit {
taskParticipants:EventPerson[] = [];
taskParticipantsCc:EventPerson[] = [];
loggeduser: LoginUserRespose;
loggeduser: UserSession;
hideExternalDomain = true;
taskType: any;
@@ -33,7 +33,7 @@
<button *ngIf="p.userPermission([p.permissionList.Gabinete.md_tasks]) && task.Status != 'Pending'" (click)="sendExpedienteToPending()" class="btn-cancel" shape="round" >Enviar para Pendentes</button>
</div>
<div class="buttons px-20" *ngIf="task.activityInstanceName == 'Concluir Despacho'">
<button *ngIf="p.userPermission([p.permissionList.Gabinete.pr_tasks])" (click)="openAddNoteModal('Concluido')" class="btn-cancel" shape="round" >Marcar como Concluído</button>
<button *ngIf="p.userPermission([p.permissionList.Gabinete.pr_tasks])" (click)="openAddNoteModal('Executado1')" class="btn-cancel" shape="round" >Marcar como Concluído</button>
<button *ngIf="p.userPermission([p.permissionList.Gabinete.pr_tasks])" (click)="openAddNoteModal('Reexecutar')" class="btn-cancel" shape="round" >Enviar para Reexecução</button>
<button *ngIf="p.userPermission([p.permissionList.Agenda.access])" (click)="openBookMeetingModal(task)" class="btn-cancel" shape="round" >Marcar Reunião</button>
<button *ngIf="p.userPermission([p.permissionList.Gabinete.pr_tasks]) && task.Status != 'Pending'" (click)="sendExpedienteToPending()" class="btn-cancel" shape="round" >Enviar para Pendentes</button>
@@ -278,6 +278,32 @@ export class DespachoPrPage implements OnInit {
}
async executadoPR(note: string, documents: any) {
let body = {
"serialNumber": this.serialNumber,
"action": "Executado",
"ActionTypeId": 95,
"dataFields": {
"ReviewUserComment": note,
},
"AttachmentList": documents,
}
const loader = this.toastService.loading()
try {
await this.processes.CompleteTask(body).toPromise()
this.httpErroHandle.httpsSucessMessagge('Executado')
this.TaskService.loadDiplomas()
} catch (error) {
this.httpErroHandle.httpStatusHandle(error)
}
finally {
loader.remove()
}
}
async arquivar(note: string, documents: any) {
let body = {
"serialNumber": this.serialNumber,
@@ -447,6 +473,8 @@ export class DespachoPrPage implements OnInit {
}
else if (actionName == 'Reexecutar') {
await this.reexecutar(res.data.note, docs);
} else if (actionName == 'Executado1') {
await this.executadoPR(res.data.note, docs)
}
this.TaskService.loadDiplomas()
@@ -3,7 +3,7 @@ import { ProcessesService } from 'src/app/services/processes.service';
import { ActivatedRoute } from '@angular/router';
import { Event } from '../../../../models/event.model';
import { MenuController, ModalController, PopoverController } from '@ionic/angular';
import { momentG } from 'src/plugin/momentG'
import { momentG } from 'src/plugin/momentG';
import { DiscartExpedientModalPage } from '../../discart-expedient-modal/discart-expedient-modal.page';
import { BookMeetingModalPage } from '../../expediente/book-meeting-modal/book-meeting-modal.page';
import { CreateProcessPage } from 'src/app/modals/create-process/create-process.page';
@@ -6,6 +6,7 @@
[task]=task
[intervenientes]=intervenientes
[cc]=cc
[fulltask]="fulltask"
[customDate]=customDate
[mergedArray]="mergedArray"
(openOptions)= openOptions()
@@ -88,6 +88,7 @@ export class DiplomaAssinarPage implements OnInit {
}
async openOptions(taskAction?: any) {
console.log('openOptions')
if (window.innerWidth > 500) {
this.showOptions = true
@@ -139,11 +140,12 @@ export class DiplomaAssinarPage implements OnInit {
"TaskStartDate": res.taskStartDate,
"InstanceID": res.workflowInstanceDataFields.InstanceID,
"FolderID": res.workflowInstanceDataFields.FolderID,
"DraftIds": res.workflowInstanceDataFields?.DraftIds
"DraftIds": res.workflowInstanceDataFields?.DraftIds,
}
console.log('draftidsss',res.workflowInstanceDataFields.DraftIds);
this.fulltask = res;
console.log('this.fulltask', this.fulltask )
let stringDraft = res.workflowInstanceDataFields.DraftIds;
this.DraftIds = res.workflowInstanceDataFields.DraftIds
console.log('draftidsss 111',this.DraftIds);
@@ -107,7 +107,7 @@
<div class="aside-right flex-column height-100">
<div class="aside-buttons" >
<button (click)="approveTask(loadedEvent.serialNumber)" full class="btn-cancel" shape="round" >Aprovar</button>
<button (click)="editar(loadedEvent.serialNumber)" full class="btn-cancel" shape="round" >Editar evento</button>
<button (click)="editar(loadedEvent.serialNumber)" full class="btn-cancel" shape="round" *ngIf="p.userPermission([p.permissionList.Agenda.creatEvent])">Editar evento</button>
<button (click)="emendTask(loadedEvent.serialNumber)" class="btn-cancel" shape="round" >Enviar para Revisão</button>
<button (click)="rejeitar(loadedEvent.serialNumber)" full class="btn-delete" shape="round" >Eliminar</button>
</div>
@@ -7,7 +7,7 @@ import { DiscartExpedientModalPage } from '../../discart-expedient-modal/discart
import { AttachmentsService } from 'src/app/services/attachments.service';
import { SearchPage } from 'src/app/pages/search/search.page';
import { SearchList } from 'src/app/models/search-document';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { AttendeesPageModal } from 'src/app/pages/events/attendees/attendees.page';
import { ToastService } from 'src/app/services/toast.service';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@@ -111,7 +111,7 @@ export class BookMeetingModalPage implements OnInit {
sessionStore = SessionStore;
SessionStore=SessionStore
environment = environment
loggeduser: LoginUserRespose;
loggeduser: UserSession;
eventPersons: EventPerson[];
contacts: EventPerson[];
@@ -12,7 +12,7 @@ import { ExpedienteDetailPage } from '../expediente-detail/expediente-detail.pag
import { AlertService } from 'src/app/services/alert.service';
import { SearchPage } from 'src/app/pages/search/search.page';
import { SearchList } from 'src/app/models/search-document';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { ToastService } from 'src/app/services/toast.service';
import { AttendeesPageModal } from 'src/app/pages/events/attendees/attendees.page';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@@ -98,7 +98,7 @@ export class ExpedientTaskModalPage implements OnInit {
taskResult: any = {}
loggeduser: LoginUserRespose;
loggeduser: UserSession;
toppings = new FormControl();
Form: FormGroup;
@@ -371,6 +371,7 @@ export class ExpedientTaskModalPage implements OnInit {
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs,
dataFields: {}
}
let action_despacho = {
@@ -405,7 +406,8 @@ export class ExpedientTaskModalPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
let action_parecer = {
@@ -437,7 +439,8 @@ export class ExpedientTaskModalPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
//
let action_deferimento = {
@@ -475,6 +478,7 @@ export class ExpedientTaskModalPage implements OnInit {
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs,
dataFields: {}
}
@@ -519,7 +523,8 @@ export class ExpedientTaskModalPage implements OnInit {
UserEmail: this.loggeduser.Email,
UsersSelected: attendees,
DispatchFolder: this.dispatchFolder,
AttachmentList: docs
AttachmentList: docs,
dataFields: {}
}
let action_parecer_pr = {
@@ -26,7 +26,7 @@ import { NewGroupPage } from 'src/app/ui/chat/modal/new-group/new-group.page';
import { DataService } from 'src/app/services/data.service';
import { RouteService } from 'src/app/services/route.service';
import { Storage } from '@ionic/storage';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { SessionStore } from 'src/app/store/session.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { TaskService } from 'src/app/services/task.service';
@@ -61,7 +61,7 @@ export class ExpedienteDetailPage implements OnInit {
onlinecheck: boolean;
loggeduser: LoginUserRespose;
loggeduser: UserSession;
showOptions = false
constructor(
@@ -7,7 +7,7 @@ import { ViewEventPage } from 'src/app/ui/agenda/modal/view-event/view-event.pag
import { DiscartExpedientModalPage } from '../../discart-expedient-modal/discart-expedient-modal.page';
import { ExpedientTaskModalPage } from '../../expediente/expedient-task-modal/expedient-task-modal.page';
import { BookMeetingModalPage } from '../../expediente/book-meeting-modal/book-meeting-modal.page';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { AddNotePage } from 'src/app/modals/add-note/add-note.page';
import { OptsExpedientePrPage } from 'src/app/shared/popover/opts-expediente-pr/opts-expediente-pr.page';
import { ToastService } from 'src/app/services/toast.service';
@@ -41,7 +41,7 @@ export class ExpedientePrPage implements OnInit {
intervenientes: any = [];
cc: any = [];
loggeduser: LoginUserRespose;
loggeduser: UserSession;
documents: SearchList[] = [];
attachments:any;
isDelegated: boolean;
@@ -4,7 +4,7 @@ import { CalendarComponent } from 'ionic2-calendar';
import { ProcessesService } from 'src/app/services/processes.service';
import { ModalController } from '@ionic/angular';
import { ExpedienteDetailPage } from 'src/app/pages/gabinete-digital/expediente/expediente-detail/expediente-detail.page';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { ExpedienteGdStore } from 'src/app/store/expedientegd-store.service';
import { ExpedienteTaskPipe } from 'src/app/pipes/expediente-task.pipe';
import { ThemeService } from 'src/app/services/theme.service'
@@ -26,7 +26,7 @@ export class ExpedientesPrPage implements OnInit {
serialNumber:string;
showLoader:boolean;
loggeduser: LoginUserRespose;
loggeduser: UserSession;
@Output() openExpedientDetail:EventEmitter<any> = new EventEmitter<any>();
skeletonLoader = true
@@ -150,11 +150,11 @@
</div>
<!-- {{ segmentVista }}: segmentVista -->
<div #scroll [ngSwitch]="segmentVista" class="overflow-y-auto">
<!-- This is the list view -->
<div *ngSwitchCase="'listview'">
<ion-item-sliding *ngIf="TaskService.loadCount || (AllProcess.length >= 1 && TaskService.loadNum >= 1)">
<div class="listview">
<ion-list *ngIf="AllProcess">
@@ -1,7 +1,7 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import {NavigationEnd, NavigationExtras, Router } from '@angular/router';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { ExpedientsPage } from 'src/app/shared/gabinete-digital/expedients/expedients.page';
import { PendentesPage } from 'src/app/shared/gabinete-digital/pendentes/pendentes.page';
import { EventsToApprovePage } from 'src/app/shared/gabinete-digital/events-to-approve/events-to-approve.page';
@@ -57,7 +57,7 @@ export class GabineteDigitalPage implements OnInit {
serialNumber: string;
loggeduser: LoginUserRespose;
loggeduser: UserSession;
mdgpr = "MDGPR";
pr = "PR";
@@ -461,8 +461,11 @@ export class GabineteDigitalPage implements OnInit {
async loadAllProcesses() {
this.skeletonLoader = true
try {
await this.TaskService.LoadTask();
this.dynamicSearch();
} catch (e) {}
this.skeletonLoader = false
}
@@ -10,7 +10,7 @@ import { CreateProcessPage } from 'src/app/modals/create-process/create-process.
import { DelegarPage } from 'src/app/modals/delegar/delegar.page';
import { DarParecerPage } from 'src/app/modals/dar-parecer/dar-parecer.page';
import { AddNotePage } from 'src/app/modals/add-note/add-note.page';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { ToastService } from 'src/app/services/toast.service';
import { ForwardPage } from 'src/app/modals/forward/forward.page';
@@ -47,7 +47,7 @@ export class PedidoPage implements OnInit {
caller: string;
intervenientes: any = []
cc: any = [];
loggeduser: LoginUserRespose;
loggeduser: UserSession;
taskArrayActions = [];
showOptions = false
@@ -6,7 +6,7 @@ import { customTask } from '../../../models/dailyworktask.model';
import { ProcessesService } from 'src/app/services/processes.service';
import { AlertService } from 'src/app/services/alert.service';
import { PendentesStore } from 'src/app/store/pendestes-store.service';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { AuthService } from 'src/app/services/auth.service';
import { CustomTaskPipe } from 'src/app/pipes/custom-task.pipe';
@@ -31,7 +31,7 @@ export class PendentesPage implements OnInit {
serialNumber: string;
totalDocs: any;
showLoader: boolean;
loggeduser: LoginUserRespose;
loggeduser: UserSession;
@Input() profile: string;
segment: string;
+4 -3
View File
@@ -86,7 +86,7 @@ export class InactivityPage implements OnInit {
// if current attemp is equal to the current user
if (attempt.UserId == SessionStore.user.UserId) {
await this.authService.SetSession(attempt, this.userattempt);
// await this.authService.SetSession(attempt, this.userattempt);
if (this.p.userPermission(this.p.permissionList.Chat.access)) {
// this.authService.loginChat();
@@ -101,7 +101,7 @@ export class InactivityPage implements OnInit {
window.localStorage.clear();
SessionStore.setInativity(true)
await this.authService.SetSession(attempt, this.userattempt);
// await this.authService.SetSession(attempt, this.userattempt);
}
this.enterWithPassword = false
@@ -174,7 +174,8 @@ export class InactivityPage implements OnInit {
if (this.p.userPermission(this.p.permissionList.Agenda.access) || this.p.userPermission(this.p.permissionList.Gabinete.access)) {
//When user has got access to Agenda but does not have their own calendar, goes to Agenda
if (this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore?.user?.OwnerCalendars?.length == 0) {
//if (this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore?.user?.OwnerCalendars?.length == 0) {
if (this.p.userPermission(this.p.permissionList.Agenda.access)) {
this.router.navigate(['/home/agenda']);
}
else {
+3 -1
View File
@@ -7,13 +7,15 @@ import { IonicModule } from '@ionic/angular';
import { LoginPageRoutingModule } from './login-routing.module';
import { LoginPage } from './login.page';
import { UserModule } from 'src/app/module/user/user.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
LoginPageRoutingModule
LoginPageRoutingModule,
UserModule
],
declarations: [
LoginPage
+22 -24
View File
@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from 'src/app/services/auth.service';
import { UserForm } from 'src/app/models/user.model';
import { ToastService } from 'src/app/services/toast.service';
import { environment } from 'src/environments/environment';
@@ -21,7 +20,9 @@ import { NotificationRepositoryService } from 'src/app/module/notification/data/
import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service';
import { RoomLocalRepository } from 'src/app/module/chat/data/repository/room/room-local-repository.service'
import { MessageLocalDataSourceService } from 'src/app/module/chat/data/repository/message/message-local-data-source.service'
import { UserService } from 'src/app/module/user/domain/user.service'
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { LoginError } from 'src/app/core/user/use-case/user-login-use-case.service';
@Component({
selector: 'app-login',
@@ -47,14 +48,12 @@ export class LoginPage implements OnInit {
constructor(
private notificatinsservice: NotificationsService,
private router: Router,
private authService: AuthService,
private toastService: ToastService,
public alertController: AlertController,
private clearStoreService: ClearStoreService,
private changeProfileService: ChangeProfileService,
public ThemeService: ThemeService,
public p: PermissionService,
// public ChatSystemService: ChatSystemService,
private platform: Platform,
private storage: Storage,
private storageService: StorageService,
@@ -63,7 +62,9 @@ export class LoginPage implements OnInit {
private NotificationRepositoryService: NotificationRepositoryService,
private ChatServiceService: ChatServiceService,
private RoomLocalRepository: RoomLocalRepository,
private MessageLocalDataSourceService: MessageLocalDataSourceService
private MessageLocalDataSourceService: MessageLocalDataSourceService,
private UserService:UserService,
private httpErroHandle: HttpErrorHandle,
) { }
ngOnInit() { }
@@ -132,29 +133,26 @@ export class LoginPage implements OnInit {
const loader = this.toastService.loading()
let attempt = await this.authService.login(this.userattempt, { saveSession: false })
/* const data = await this.authService.loginContenteProduction(this.userattempt, { saveSession: true }) */
let attempt = await this.UserService.login({
username: newUserName.trim(),
password: this.password.trim(),
})
loader.remove()
if (attempt) {
if (attempt.isOk()) {
if (attempt.UserId == SessionStore.user.UserId) {
if (attempt.value.UserId == SessionStore.user.UserId) {
await this.authService.SetSession(attempt, this.userattempt);
// await this.authService.SetSession(attempt.value, this.userattempt);
this.changeProfileService.run();
if (attempt.ChatData) {
try {
await this.AgendaDataRepositoryService.getSharedCalendar()
this.NotificationHolderService.clear()
await this.authService.loginToChatWs();
this.NotificationRepositoryService.init()
@@ -162,8 +160,6 @@ export class LoginPage implements OnInit {
console.log("faild to clear chat")
}
}
this.changeProfileService.runLogin();
this.getToken();
@@ -189,7 +185,7 @@ export class LoginPage implements OnInit {
window.localStorage.clear();
this.storage.clear();
await this.authService.SetSession(attempt, this.userattempt);
// await this.authService.SetSession(attempt.value, this.userattempt);
this.NotificationRepositoryService.init()
/* CPSession.save(data) */
@@ -213,10 +209,11 @@ export class LoginPage implements OnInit {
SessionStore.hasPassLogin = true;
}
}/*
else{
this.toastService._badRequest('Ocorreu um problema por favor valide o username e password');
} */
} else {
if( typeof attempt.error == 'number') {
this.httpErroHandle.httpStatusHandle({ status: attempt.error as LoginError})
}
}
}
else {
this.toastService._badRequest('Por favor, insira a sua palavra-passe');
@@ -236,8 +233,9 @@ export class LoginPage implements OnInit {
} else {
if (this.p.userPermission(this.p.permissionList.Agenda.access) || this.p.userPermission(this.p.permissionList.Gabinete.access)) {
//When user has got access to Agenda but does not have their own calendar, goes to Agenda
if (this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore?.user?.OwnerCalendars.length == 0) {
this.router.navigate(['/home/agenda']);
//if (this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore?.user?.OwnerCalendars.length == 0) {
if (this.p.userPermission(this.p.permissionList.Agenda.access)) {
this.router.navigate(['/home/events']);
}
else {
this.router.navigate(['/home/events']);
+2 -2
View File
@@ -3,7 +3,7 @@ import { Attachment } from '../models/attachment.model';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { LoginUserRespose } from '../models/user.model';
import { UserSession } from '../models/user.model';
import { SessionStore } from '../store/session.service';
import { File } from '@ionic-native/file/ngx';
import { Platform } from '@ionic/angular';
@@ -14,7 +14,7 @@ import { ChangeProfileService } from './change-profile.service';
})
export class AttachmentsService {
loggeduser: LoginUserRespose;
loggeduser: UserSession;
headers: HttpHeaders;
constructor(
+70 -186
View File
@@ -1,7 +1,7 @@
import { Injectable, ErrorHandler } from '@angular/core';
import { StorageService } from './storage.service';
import { HttpClient, HttpHeaders, HttpEventType } from '@angular/common/http';
import { LoginUserRespose, UserForm, UserSession } from '../models/user.model';
import { UserForm, UserSession } from '../models/user.model';
import { environment } from 'src/environments/environment';
import { BehaviorSubject, of } from 'rxjs';
import { AlertController, Platform } from '@ionic/angular';
@@ -15,6 +15,7 @@ import { PermissionService } from './permission.service';
import { HttpErrorHandle } from 'src/app/services/http-error-handle.service';
import { captureException } from '@sentry/angular';
import { catchError, tap } from 'rxjs/operators';
import { UserLoginOutput } from '../core/user/use-case/user-login-use-case.service';
@Injectable({
providedIn: 'root'
})
@@ -42,35 +43,9 @@ export class AuthService {
private errorHandler: ErrorHandler,
private platform: Platform,) {
if (SessionStore.exist) {
if (this.p.userPermission(this.p.permissionList.Chat.access) == true) {
this.loginToChatWs()
}
}
window.addEventListener('focus', (event) => {
if (!this.tabIsActive) {
this.tabIsActive = true
const data = SessionStore.getDataFromLocalStorage();
if (!data?.user?.Authorization && SessionStore?.user?.Authorization) {
window.location.reload();
}
if (window['all-process-gabinete']) {
window['all-process-gabinete']()
}
}
});
window.addEventListener('blur', (event) => {
this.tabIsActive = false
});
}
async login(user: UserForm, { saveSession = true }): Promise<LoginUserRespose> {
async login(user: UserForm, { saveSession = true }): Promise<UserSession> {
user.BasicAuthKey = btoa(user.username + ':' + this.aesencrypt.encrypt(user.password, user.username));
this.headers = this.headers.set('Authorization', user.BasicAuthKey);
@@ -95,11 +70,11 @@ export class AuthService {
let response: any;
try {
response = await this.http.post<LoginUserRespose>(environment.apiURL + "UserAuthentication/Login", body, this.opts).toPromise();
response = await this.http.post<UserSession>(environment.apiURL + "UserAuthentication/Login", body, this.opts).toPromise();
if (saveSession) {
this.SetSession(response, user)
// this.SetSession(response, user)
}
} catch (error) {
this.errorHandler.handleError(error);
@@ -116,128 +91,37 @@ export class AuthService {
}
async loginContenteProduction(user: UserForm, { saveSession = true }): Promise<LoginUserRespose> {
user.BasicAuthKey = 'Basic ' + btoa(user.username + ':' + this.aesencrypt.encrypt(user.password, user.username));
// async loginContenteProduction(user: UserForm, { saveSession = true }): Promise<UserSession> {
// user.BasicAuthKey = 'Basic ' + btoa(user.username + ':' + this.aesencrypt.encrypt(user.password, user.username));
this.headers = this.headers.set('Authorization', user.BasicAuthKey);
this.opts = {
headers: this.headers,
}
// this.headers = this.headers.set('Authorization', user.BasicAuthKey);
// this.opts = {
// headers: this.headers,
// }
let response: any;
// let response: any;
try {
response = await this.http.post<LoginUserRespose>(environment.apiURL + "UserAuthentication/Login", '', this.opts).toPromise();
console.log('JWT', response)
// try {
// response = await this.http.post<UserSession>(environment.apiURL + "UserAuthentication/Login", '', this.opts).toPromise();
// console.log('JWT', response)
if (saveSession) {
/* this.SetSession(response, user) */
console.log('teste', response);
// if (saveSession) {
// /* this.SetSession(response, user) */
// console.log('teste', response);
return response
// return response
}
} catch (error) {
this.httpErroHandle.httpStatusHandle(error)
} finally {
return response
}
// }
// } catch (error) {
// this.httpErroHandle.httpStatusHandle(error)
// } finally {
// return response
// }
}
// }
// async UpdateLogin() {}
SetSession(response: LoginUserRespose, user: UserForm) {
const session: UserSession = Object.assign(SessionStore.user, response)
if (response) {
if (session.RoleID == 100000014) {
session.Profile = 'PR'
} else if (session.RoleID == 100000011) {
session.Profile = 'MDGPR'
} else if (session.RoleID == 99999872) {
session.Profile = 'Consultant'
} else if (session.RoleID == 99999886) {
session.Profile = 'SGGPR'
} else {
session.Profile = 'Unknown'
}
session.Password = user.password
session.BasicAuthKey = user.BasicAuthKey
SessionStore.reset(session)
return true;
}
this.initialsService.getInitials(session.FullName);
}
loginToChatWs() {
setTimeout(() => {
if (SessionStore.user.ChatData?.data) {
// this.RochetChatConnectorService.logout();
// this.RochetChatConnectorService.connect();
// this.RochetChatConnectorService.login().then((message: any) => {
// console.log('Chat login', message)
// SessionStore.user.RochetChatUserId = message.result.id
// SessionStore.save()
// this.ChatSystemService.loadChat()
// this.RochetChatConnectorService.setStatus('online')
// window['RochetChatConnectorService'] = this.RochetChatConnectorService
// setTimeout(() => {
// this.ChatSystemService.getAllRooms();
// this.RochetChatConnectorService.setStatus('online')
// }, 200);
// }).catch((error) => {
// console.error(SessionStore.user.ChatData, 'web socket login', error)
// if(window.location.pathname.includes('/home/')) {
// setTimeout(() => {
// this.loginToChatWs();
// }, 4000)
// }
// })
}
// before sending a message with a attachment
8
// this.NfService.downloadFileMsg = async (message: MessageService, room?: RoomService) => {
// //
// let downloadFile = "";
// if (message.file.type == "application/img") {
// const event: any = await this.AttachmentsService.downloadFile(message.file.guid).toPromise();
// if (event.type === HttpEventType.DownloadProgress) {
// //this.downloadProgess = Math.round((100 * event.loaded) / event.total);
// return true
// } else if (event.type === HttpEventType.Response) {
// downloadFile = 'data:image/jpeg;base64,' + btoa(new Uint8Array(event.body).reduce((data, byte) => data + String.fromCharCode(byte), ''));
// message.file = {
// guid: message.file.guid,
// image_url: downloadFile,
// type: message.file.type
// }
// return true
// }
// return false
// }
// };
}, 1)
}
autologout(expirationDate: number) {
setTimeout(() => {
this.logout();
@@ -268,50 +152,50 @@ export class AuthService {
await alert.present();
}
async logoutUser() {
// async logoutUser() {
this.headers = this.headers.set('Authorization', 'Bearer ' + SessionStore.user.Authorization);
// this.headers = this.headers.set('Authorization', 'Bearer ' + SessionStore.user.Authorization);
this.opts = {
headers: this.headers,
}
let response: any;
try {
response = await this.http.delete<LoginUserRespose>(environment.apiURL + "userauthentication/Logout", this.opts).toPromise();
SessionStore.user.Authorization = "";
SessionStore.user.RefreshToken = "";
} catch (error) {
this.errorHandler.handleError(error);
this.httpErroHandle.loginHttpStatusHandle(error)
captureException(error);
if(error?.status == 403) {
console.log('error?.status == 403')
}
} finally {
return response
}
}
refreshToken() {
return this.http
.put<any>(environment.apiURL + "UserAuthentication/RefreshToken", {
refreshToken: SessionStore.user.RefreshToken,
},)
.pipe(
tap((tokens) => {
console.log(tokens)
SessionStore.user.Authorization = tokens.Authorization;
SessionStore.user.RefreshToken = tokens.refreshToken;
}),
catchError((error) => {
this.logoutUser();
return of(false);
})
);
}
// this.opts = {
// headers: this.headers,
// }
// let response: any;
// try {
// response = await this.http.delete<UserSession>(environment.apiURL + "userauthentication/Logout", this.opts).toPromise();
// SessionStore.user.Authorization = "";
// SessionStore.user.RefreshToken = "";
// } catch (error) {
// this.errorHandler.handleError(error);
// this.httpErroHandle.loginHttpStatusHandle(error)
// captureException(error);
// if(error?.status == 403) {
// console.log('error?.status == 403')
// }
// } finally {
// return response
// }
// }
// refreshToken() {
// return this.http
// .put<any>(environment.apiURL + "UserAuthentication/RefreshToken", {
// refreshToken: SessionStore.user.RefreshToken,
// },)
// .pipe(
// tap((tokens) => {
// console.log(tokens)
// SessionStore.user.Authorization = tokens.Authorization;
// SessionStore.user.RefreshToken = tokens.refreshToken;
// }),
// catchError((error) => {
// this.logoutUser();
// return of(false);
// })
// );
// }
}
@@ -33,7 +33,7 @@ export function APIReturn(schema: z.ZodTypeAny, path: string) {
tracing?.setAttribute?.('map.error.schema-'+i, JSON.stringify(schema))
}
tracing.log('API return '+ path, {
tracing?.log?.('API return '+ path, {
data: result?.value,
issues: error?.errors
})
@@ -79,7 +79,7 @@ export function APINODReturn(schema: z.ZodTypeAny, data , path: string, tracing?
tracing?.setAttribute('map.error.schema-'+i, JSON.stringify(schema))
}
tracing.log('API return '+ path, {
tracing?.log?.('API return '+ path, {
data,
issues: error?.errors
})
+2 -1
View File
@@ -18,7 +18,8 @@ export class FirstEnterService {
enter( ) {
if(this.p.userPermission(this.p.permissionList.Agenda.access) || this.p.userPermission(this.p.permissionList.Gabinete.access)){
//When user has got access to Agenda but does not have their own calendar, goes to Agenda
if(this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore.user?.OwnerCalendars?.length == 0){
//if(this.p.userPermission(this.p.permissionList.Agenda.access) && SessionStore.user?.OwnerCalendars?.length == 0){
if(this.p.userPermission(this.p.permissionList.Agenda.access)) {
this.router.navigate(['/home/agenda']);
}
else{
@@ -37,6 +37,7 @@ function createProvider(serviceName) {
// Example usage:
export const OpentelemetryChatProvider = createProvider('FO-chat-service');
export const OpentelemetryUserProvider = createProvider('FO-User-service');
export const OpentelemetryAgendaProvider = createProvider('FO-agenda-service');
export const OpentelemetryNotificationProvider = createProvider('FO-notification');
export const OpentelemetryInterceptorProvider = createProvider('FO-interceptor');
@@ -1,7 +1,7 @@
import { v4 as uuidv4 } from 'uuid';
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
import { Tracer, Span } from '@opentelemetry/sdk-trace-base';
import { OpentelemetryAgendaProvider, OpentelemetryChatProvider, OpentelemetryInterceptorProvider, OpentelemetryLogging, OpentelemetryNotificationProvider } from './opentelemetry';
import { OpentelemetryAgendaProvider, OpentelemetryChatProvider, OpentelemetryInterceptorProvider, OpentelemetryLogging, OpentelemetryNotificationProvider, OpentelemetryUserProvider } from './opentelemetry';
import { Device, DeviceInfo } from '@capacitor/device';
import { SessionStore } from 'src/app/store/session.service';
import { environment } from 'src/environments/environment';
@@ -14,6 +14,9 @@ import { Logger } from '../../logger/main/service';
const tracerInstance = OpentelemetryAgendaProvider.getTracer('example-tracer-hole', '111', {})
const tracerNotificationInstance = OpentelemetryNotificationProvider.getTracer('example-tracer-hole', '111', {})
const tracerChat = OpentelemetryChatProvider.getTracer('OpentelemetryChatProvider','some' ,{})
const tracerUser = OpentelemetryUserProvider.getTracer('OpentelemetryUserProvider','some' ,{})
let device: DeviceInfo;
Device.getInfo().then(e => {
@@ -49,6 +52,8 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish, waitNThrow =
_tracerInstance = tracerNotificationInstance
} else if (module == 'chat') {
_tracerInstance = tracerChat
} else if (module == 'user') {
_tracerInstance = tracerUser
} else {
_tracerInstance = tracerInstance
}
@@ -151,7 +156,7 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish, waitNThrow =
const duration = Date.now() - (startTime as unknown as number);
useCaseDurationHistogram.record(duration, { use_case: name });
useCaseDurationHistogram.record(duration, { use_case: name, user: SessionStore.user.UserName });
useCaseDurationHistogram.record(duration, { use_case: name, user: SessionStore.user.FullName || 'No User' });
finish = true
},
@@ -161,7 +166,7 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish, waitNThrow =
data.errors.push(message)
data.status = {code: SpanStatusCode.ERROR, message}
span.setStatus({code: SpanStatusCode.ERROR, message})
Logger.error(message, {...obj, spanId, name})
Logger.error(message, {...obj, spanId, name, ...data})
},
createSpan: (name, parent?: any) => {
return tracerInstance.startSpan(name, { root: false }, parent) as Span;
@@ -16,7 +16,7 @@ export class NotificationsEndsPointsService {
postToken(token) {
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
// const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const body = {
UserId: SessionStore.user.UserId,
TokenId: token,
@@ -24,17 +24,17 @@ export class NotificationsEndsPointsService {
Service: 1
};
return this.http.post<Token>(`${environment.apiURL}+ 'notifications/token'`, body, { headers })
return this.http.post<Token>(`${environment.apiURL}+ 'notifications/token'`, body, { })
}
DeleteToken(token) {
const geturl = environment.apiURL + `notifications/token?userId=${SessionStore.user.UserId}&tokenId=${token}`;
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const body = {};
return this.http.delete<Token>(`${geturl}`, { headers, body })
return this.http.delete<Token>(`${geturl}`, { body })
}
}
@@ -16,55 +16,55 @@ export class NotificationsTriggerService {
sendNotificationWithSend(userID, title, bodymsg, roomId) {
const geturl = environment.apiURL + `notifications/send`;
// sendNotificationWithSend(userID, title, bodymsg, roomId) {
// const geturl = environment.apiURL + `notifications/send`;
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const message = {
"Service": "chat",
"IdObject": roomId
}
let id = 437
this.http.post<Token>(geturl + `?userId=${userID}&title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
}, (error) => {
})
}
ChatSendMessageNotification(userID, title, bodymsg, roomId) {
const geturl = environment.apiURL + `notifications/sendbyUsername`;
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const message = {
"Service": "chat",
"IdObject": roomId
}
let id = 437
this.http.post<Token>(geturl + `?username=${userID}&title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
// this.active = true
}, (error) => {
})
}
ChatSendMessageNotificationGrup(usersID, title, bodymsg, roomId) {
const geturl = environment.apiURL + `notifications/sendByUsernames`;
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const message = {
"Users": usersID,
"NotificationData": {
"Service": "chat",
"IdObject": roomId
}
}
this.http.post<Token>(geturl + `?title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
// this.active = true
}, (error) => {
})
}
// const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
// const message = {
// "Service": "chat",
// "IdObject": roomId
// }
// let id = 437
// this.http.post<Token>(geturl + `?userId=${userID}&title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
// }, (error) => {
// })
// }
// ChatSendMessageNotification(userID, title, bodymsg, roomId) {
// const geturl = environment.apiURL + `notifications/sendbyUsername`;
// const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
// const message = {
// "Service": "chat",
// "IdObject": roomId
// }
// let id = 437
// this.http.post<Token>(geturl + `?username=${userID}&title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
// // this.active = true
// }, (error) => {
// })
// }
// ChatSendMessageNotificationGrup(usersID, title, bodymsg, roomId) {
// const geturl = environment.apiURL + `notifications/sendByUsernames`;
// const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
// const message = {
// "Users": usersID,
// "NotificationData": {
// "Service": "chat",
// "IdObject": roomId
// }
// }
// this.http.post<Token>(geturl + `?title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
// // this.active = true
// }, (error) => {
// })
// }
}
+52 -49
View File
@@ -158,9 +158,9 @@ export class NotificationsService {
tracing.setAttribute('outcome', 'success')
},
(error) => {
console.error('Permission denied:', error);
tracing.setAttribute('notification.token', 'false')
tracing.setAttribute('outcome', 'failed')
tracing.hasError('Permission denied: request token');
}
);
}
@@ -168,13 +168,16 @@ export class NotificationsService {
DeletePostToken() {
if(this.token) {
const geturl = environment.apiURL + `notifications/token?userId=${SessionStore.user.UserId}&tokenId=${this.token}`;
this.DeleteToken(geturl)
}
}
postToken(token, geturl, tracing: TracingType) {
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
//const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const body = {
UserId: SessionStore.user.UserId,
TokenId: token,
@@ -183,7 +186,7 @@ export class NotificationsService {
};
tracing.setAttribute('token.data', token)
this.http.post<Tokenn>(`${geturl}`, body, { headers }).subscribe(data => {
this.http.post<Tokenn>(`${geturl}`, body, { }).subscribe(data => {
this.active = true
tracing.setAttribute('outcome','success')
tracing.finish()
@@ -196,10 +199,10 @@ export class NotificationsService {
DeleteToken(geturl) {
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const body = {};
this.http.delete<Tokenn>(`${geturl}`, { headers, body }).subscribe(data => {
this.http.delete<Tokenn>(`${geturl}`, { body }).subscribe(data => {
this.active = true
}, (error) => {
@@ -300,57 +303,57 @@ export class NotificationsService {
}
sendNotificationWithSend(userID, title, bodymsg, roomId) {
const geturl = environment.apiURL + `notifications/send`;
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const message = {
"Service": "chat",
"IdObject": roomId
}
let id = 437
this.http.post<Tokenn>(geturl + `?userId=${userID}&title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
this.active = true
}, (error) => {
})
}
// sendNotificationWithSend(userID, title, bodymsg, roomId) {
// const geturl = environment.apiURL + `notifications/send`;
ChatSendMessageNotification(userID, title, bodymsg, roomId) {
const geturl = environment.apiURL + `notifications/sendbyUsername`;
// const message = {
// "Service": "chat",
// "IdObject": roomId
// }
// let id = 437
// this.http.post<Tokenn>(geturl + `?userId=${userID}&title=${title}&body=${bodymsg}`, message, { }).subscribe(data => {
// this.active = true
// }, (error) => {
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const message = {
"Service": "chat",
"IdObject": roomId
}
let id = 437
this.http.post<Tokenn>(geturl + `?username=${userID}&title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
this.active = true
}, (error) => {
// })
// }
})
}
ChatSendMessageNotificationGrup(usersID, title, bodymsg, roomId) {
const geturl = environment.apiURL + `notifications/sendByUsernames`;
// ChatSendMessageNotification(userID, title, bodymsg, roomId) {
// const geturl = environment.apiURL + `notifications/sendbyUsername`;
const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
const message = {
"Users": usersID,
"NotificationData": {
"Service": "chat",
"IdObject": roomId
}
}
this.http.post<Tokenn>(geturl + `?title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
this.active = true
}, (error) => {
// const message = {
// "Service": "chat",
// "IdObject": roomId
// }
// let id = 437
// this.http.post<Tokenn>(geturl + `?username=${userID}&title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
// this.active = true
// }, (error) => {
})
}
// })
// }
// ChatSendMessageNotificationGrup(usersID, title, bodymsg, roomId) {
// const geturl = environment.apiURL + `notifications/sendByUsernames`;
// const headers = { 'Authorization': SessionStore.user.BasicAuthKey };
// const message = {
// "Users": usersID,
// "NotificationData": {
// "Service": "chat",
// "IdObject": roomId
// }
// }
// this.http.post<Tokenn>(geturl + `?title=${title}&body=${bodymsg}`, message, { headers }).subscribe(data => {
// this.active = true
// }, (error) => {
// })
// }
tempClearArray(data) {
this.DataArray = new Array;
+2 -2
View File
@@ -4,7 +4,7 @@ import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { AuthService } from '../services/auth.service';
import { LoginUserRespose } from '../models/user.model';
import { UserSession } from '../models/user.model';
import { OrganicEntity } from 'src/app/models/organic-entity.model';
import { SessionStore } from '../store/session.service';
import { ChangeProfileService } from './change-profile.service';
@@ -15,7 +15,7 @@ import { ChangeProfileService } from './change-profile.service';
export class OrganicEntityService {
authheader = {};
loggeduser: LoginUserRespose;
loggeduser: UserSession;
headers: HttpHeaders;
constructor(
+32 -50
View File
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { LoginUserRespose } from '../models/user.model';
import { UserSession } from '../models/user.model';
import { environment } from 'src/environments/environment';
import { Observable } from 'rxjs';
import { DocumentSetUpMeeting } from '../models/CallMeeting';
@@ -16,9 +16,7 @@ import { SessionStore } from '../store/session.service';
export class ProcessesService {
authheader = {};
loggeduser: LoginUserRespose;
headers: HttpHeaders;
headers2: HttpHeaders;
loggeduser: UserSession;
@@ -40,17 +38,7 @@ export class ProcessesService {
}
setHeader() {
this.headers = new HttpHeaders();;
this.headers = this.headers.set('Authorization', 'Bearer ' + SessionStore.user.Authorization);
this.headers2 = new HttpHeaders();;
this.headers2 = this.headers2.set('Authorization', 'Bearer ' + SessionStore.user.Authorization);
}
setHeader() {}
uploadFile(formData: any) {
@@ -58,7 +46,6 @@ export class ProcessesService {
const geturl = environment.apiURL + 'lakefs/UploadFiles';
let options = {
headers: this.headers
};
return this.http.post(`${geturl}`, formData, options);
@@ -75,7 +62,6 @@ export class ProcessesService {
params = params.set("pageSize", "500");
let options = {
headers: this.headers,
params: params
};
@@ -91,7 +77,7 @@ export class ProcessesService {
// params = params.set("userid", userid);
// let options = {
// headers: this.headers,
//
// params: params
// };
@@ -109,7 +95,6 @@ export class ProcessesService {
params = params.set("OnlyCount", onlycount.toString());
let options = {
headers: this.headers,
params: params
};
@@ -124,7 +109,6 @@ export class ProcessesService {
params = params.set("serialNumber", serialnumber);
let options = {
headers: this.headers,
params: params
};
return this.http.get<any>(`${geturl}`, options);
@@ -138,7 +122,6 @@ export class ProcessesService {
/* params = params.set("serialNumber", serialnumber); */
let options = {
headers: this.headers2,
/* params: params */
};
return this.http.get<any>(`${geturl}`, options);
@@ -151,7 +134,7 @@ export class ProcessesService {
/* params = params.set("serialNumber", serialnumber); */
let options = {
headers: this.headers2,
/* params: params */
};
return this.http.put<any>(`${geturl}`, object, options);
@@ -164,7 +147,7 @@ export class ProcessesService {
params = params.set("serialNumber", serialNumber);
let options = {
headers: this.headers,
params: params
};
return this.http.post<any>(`${geturl}`, '', options);
@@ -177,7 +160,6 @@ export class ProcessesService {
params = params.set("onlyCount", onlyCount.toString());
let options = {
headers: this.headers,
params: params
};
@@ -188,7 +170,7 @@ export class ProcessesService {
const geturl = environment.apiURL + 'Tasks/DelegateTask';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options);
}
@@ -200,7 +182,7 @@ export class ProcessesService {
params = params.set("folderId", folderId);
let options = {
headers: this.headers,
params: params
};
return this.http.get<any>(`${geturl}`, options);
@@ -213,7 +195,7 @@ export class ProcessesService {
params = params.set("serialNumber", serialnumber);
let options = {
headers: this.headers,
params: params
};
return this.http.get<any>(`${geturl}`, options);
@@ -222,7 +204,7 @@ export class ProcessesService {
GetMDOficialTasks(): Observable<any> {
const geturl = environment.apiURL + 'tasks/GetMDOficialTasks';
let options = {
headers: this.headers,
};
return this.http.get<any>(`${geturl}`, options);
}
@@ -230,7 +212,7 @@ export class ProcessesService {
GetMDPersonalTasks(): Observable<any> {
const geturl = environment.apiURL + 'tasks/GetMDPersonalTasks';
let options = {
headers: this.headers,
};
return this.http.get<any>(`${geturl}`, options);
}
@@ -243,7 +225,7 @@ export class ProcessesService {
params = params.set("onlyCount", count);
let options = {
headers: this.headers,
params: params,
};
return this.http.get<any>(`${geturl}`, options);
@@ -253,7 +235,7 @@ export class ProcessesService {
const geturl = environment.apiURL + 'Tasks/Complete';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -262,7 +244,7 @@ export class ProcessesService {
const geturl = environment.apiURL + 'presidentialActions/signature';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -273,7 +255,7 @@ export class ProcessesService {
const geturl = environment.apiURL + 'Tasks/CompleteTask';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -282,7 +264,7 @@ export class ProcessesService {
const geturl = environment.apiURL + 'Tasks/CompleteTaskParecerPr';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -294,7 +276,7 @@ export class ProcessesService {
params = params.set("FolderId", FolderId);
let options = {
headers: this.headers,
params: params
};
return this.http.post<any>(`${geturl}`, '', options);
@@ -308,7 +290,7 @@ export class ProcessesService {
params = params.set("applicationid", FsId);
let options = {
headers: this.headers,
params: params
};
return this.http.get<any>(`${geturl}`, options);
@@ -317,7 +299,7 @@ export class ProcessesService {
postDespatcho(body: any) {
const geturl = environment.apiURL + 'Processes/CreateDispatch';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -325,7 +307,7 @@ export class ProcessesService {
postDespatchoPr(body: any) {
const geturl = environment.apiURL + 'Processes/CreateDispatchPR';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -350,7 +332,7 @@ export class ProcessesService {
const geturl = environment.apiURL + 'Processes/CreateParecer';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -374,7 +356,7 @@ export class ProcessesService {
const geturl = environment.apiURL + 'Processes/CreateParecerPR';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -382,7 +364,7 @@ export class ProcessesService {
postDeferimento(body: any) {
const geturl = environment.apiURL + 'Processes/CreateDeferimento';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, body, options)
}
@@ -390,7 +372,7 @@ export class ProcessesService {
GetActionsList() {
const geturl = environment.apiURL + 'presidentialActions';
let options = {
headers: this.headers,
};
@@ -400,7 +382,7 @@ export class ProcessesService {
GetSubjectType() {
const geturl = environment.apiURL + 'ecm/SubjectType';
let options = {
headers: this.headers,
};
return this.http.get<any>(`${geturl}`, options);
}
@@ -414,7 +396,7 @@ export class ProcessesService {
params = params.set("applicationId", FsId);
let options = {
headers: this.headers,
params: params
};
return this.http.get<any>(`${geturl}`, options);
@@ -426,7 +408,7 @@ export class ProcessesService {
url = url.replace('/V4/', '/V5/')
let options: any = {
headers: this.headers,
}
return this.http.post<any>(`${url}`, body, options);
}
@@ -442,7 +424,7 @@ export class ProcessesService {
params = params.set("SourceLocation ", 17);
let options = {
headers: this.headers,
params: params
};
return this.http.get<any>(`${geturl}`, options);
@@ -456,7 +438,7 @@ export class ProcessesService {
params = params.set("docid", DocId);
let options: any = {
headers: this.headers,
params
}
@@ -474,7 +456,7 @@ export class ProcessesService {
params = params.set("applicationId", FsId);
let options = {
headers: this.headers,
params: params
};
return this.http.get<any>(`${geturl}`, options);
@@ -484,7 +466,7 @@ export class ProcessesService {
const geturl = environment.apiURL + 'Tasks/AttachDocImage';
let options = {
headers: this.headers,
};
return this.http.post<any>(`${geturl}`, file, options);
}
@@ -495,7 +477,7 @@ export class ProcessesService {
let params = new HttpParams();
params = params.set('calendarName', calendarType);
let options = {
headers: this.headers,
params: params
};
return this.http.post<any>(`${geturl}`, body, options);
+2 -2
View File
@@ -2,7 +2,7 @@ import { Injectable, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { AuthService } from '../services/auth.service';
import { LoginUserRespose } from '../models/user.model';
import { UserSession } from '../models/user.model';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators'
import { Publication } from '../models/publication';
@@ -19,7 +19,7 @@ export class PublicationsService {
authheader = {};
loggeduser: LoginUserRespose;
loggeduser: UserSession;
headers: HttpHeaders;
constructor(private http: HttpClient, user: AuthService,
+2 -2
View File
@@ -4,7 +4,7 @@ import { Event } from '../models/event.model';
import { from, Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { AuthService } from '../services/auth.service';
import { LoginUserRespose } from '../models/user.model';
import { UserSession } from '../models/user.model';
import { EventSearch } from "src/app/models/event-search";
import { TopSearch } from 'src/app/models/top-search';
import { SessionStore } from '../store/session.service';
@@ -16,7 +16,7 @@ import { ChangeProfileService } from './change-profile.service';
export class SearchService {
// state
authheader = {};
loggeduser: LoginUserRespose;
loggeduser: UserSession;
headers: HttpHeaders;
categories= Array;
-1
View File
@@ -203,7 +203,6 @@ export class TaskService {
try {
await this.loadExpedientes()
this.loadCount = true;
} catch(error) {
this.loadCount = true;
}
@@ -4,10 +4,11 @@ import { HttpServiceService } from 'src/app/services/http/http-service.service';
import { Observable} from 'rxjs';
import { CreateEvent, EditEvent, EventDetailsDTO, EventsDTO, IuploadFileLK, refreshTokenDTO } from "./interface";
import { HttpClient, HttpEvent, HttpHeaders, HttpParams } from '@angular/common/http';
import { DetectCalendars, makeHeaderForCalendar } from '../../utils/utils';
import { z } from "zod";
import { ok, err } from 'neverthrow';
import { SessionStore } from 'src/app/store/session.service';
import { UserService } from 'src/app/module/user/domain/user.service'
/* import { ok, err } from 'neverthrow'; */
@@ -19,122 +20,114 @@ export class MiddlewareServiceService {
constructor(
private HttpServiceService: HttpServiceService,
private http: HttpClient,
private UserService:UserService
) {
window["MiddlewareServiceService"] = this
}
refreshToken(refreshToken: string) {
const data = {
refreshToken: refreshToken
}
return this.HttpServiceService.put<refreshTokenDTO>(environment.apiURL + "UserAuthentication/RefreshToken", data, {})
// .pipe(
// map((response: HttpResponse<refreshToken>) => {
// return response.body
// })
// );
}
// refreshToken(refreshToken: string) {
// this.UserService.refreshToken()
// }
// ================================ Calendar =================================================
GetEvents(startDate: string, endDate: string, calendarId): Observable<EventsDTO[]> {
// GetEvents(startDate: string, endDate: string, calendarId): Observable<EventsDTO[]> {
let geturl = environment.apiURL + 'calendar/GetEvents';
geturl = geturl.replace('/V4/', '/V5/')
// let geturl = environment.apiURL + 'calendar/GetEvents';
// geturl = geturl.replace('/V4/', '/V5/')
let params = new HttpParams();
// let params = new HttpParams();
params = params.set("StartDate", startDate);
params = params.set("EndDate", endDate);
// params = params.set("StartDate", startDate);
// params = params.set("EndDate", endDate);
const calendar = DetectCalendars(calendarId)
const header = makeHeaderForCalendar(calendar)
// const calendar = DetectCalendars(calendarId)
// const header = makeHeaderForCalendar(calendar)
let options = {
headers: header,
params: params
};
// let options = {
// headers: header,
// params: params
// };
// return this.HttpServiceService.get<Event[]>(`${geturl}`, options);
// // return this.HttpServiceService.get<Event[]>(`${geturl}`, options);
return {} as any
}
// return {} as any
// }
GetEventDetail(eventId: string, calendarId: string) {
let geturl = environment.apiURL + 'calendar/GetEvent';
let params = new HttpParams();
// GetEventDetail(eventId: string, calendarId: string) {
// let geturl = environment.apiURL + 'calendar/GetEvent';
// let params = new HttpParams();
params = params.set("EventId", eventId);
// params = params.set("EventId", eventId);
const calendar = DetectCalendars(calendarId)
const header = makeHeaderForCalendar(calendar)
// const calendar = DetectCalendars(calendarId)
// const header = makeHeaderForCalendar(calendar)
let options = {
headers: header,
params: params
}
return this.HttpServiceService.get<EventDetailsDTO>(`${geturl}`, options);
}
// let options = {
// headers: header,
// params: params
// }
// return this.HttpServiceService.get<EventDetailsDTO>(`${geturl}`, options);
// }
createEvent(event: CreateEvent, calendarName: string, CalendarId) {
const puturl = environment.apiURL + 'Calendar/PostEvent';
let params = new HttpParams();
// createEvent(event: CreateEvent, calendarName: string, CalendarId) {
// const puturl = environment.apiURL + 'Calendar/PostEvent';
// let params = new HttpParams();
if(!event.TimeZone) {
const now = new Date();
event.TimeZone = event.TimeZone = now.toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1];
}
// if(!event.TimeZone) {
// const now = new Date();
// event.TimeZone = event.TimeZone = now.toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1];
// }
if(!event.Organizer) {
event.Organizer = {
"Id": SessionStore.user.UserId,
"EmailAddress": SessionStore.user.Email,
"Name": SessionStore.user.UserName,
"IsRequired": true,
"UserType": "GD"
}
}
// if(!event.Organizer) {
// event.Organizer = {
// "Id": SessionStore.user.UserId,
// "EmailAddress": SessionStore.user.Email,
// "Name": SessionStore.user.UserName,
// "IsRequired": true,
// "UserType": "GD"
// }
// }
params = params.set("CalendarName", calendarName);
params = params.set("notifyUsers", true)
// params = params.set("CalendarName", calendarName);
// params = params.set("notifyUsers", true)
let options: any;
// let options: any;
const calendar = DetectCalendars(CalendarId)
const header = makeHeaderForCalendar(calendar)
// const calendar = DetectCalendars(CalendarId)
// const header = makeHeaderForCalendar(calendar)
options = {
headers: header,
params: params
};
// options = {
// headers: header,
// params: params
// };
return this.HttpServiceService.post<string>(`${puturl}`, event, options)
}
// return this.HttpServiceService.post<string>(`${puturl}`, event, options)
// }
editEvent(event: EditEvent, conflictResolutionMode: number, sendInvitationsOrCancellationsMode: number, CalendarId? ) {
// editEvent(event: EditEvent, conflictResolutionMode: number, sendInvitationsOrCancellationsMode: number, CalendarId? ) {
let options: any;
// let options: any;
const calendar = DetectCalendars(CalendarId)
const header = makeHeaderForCalendar(calendar)
let params = new HttpParams();
// const calendar = DetectCalendars(CalendarId)
// const header = makeHeaderForCalendar(calendar)
// let params = new HttpParams();
params = params.set("conflictResolutionMode", conflictResolutionMode.toString());
params = params.set("sendInvitationsOrCancellationsMode", sendInvitationsOrCancellationsMode.toString());
params.set('CalendarId', event.CalendarId)
params.set('CalendarName', event.CalendarName)
// params = params.set("conflictResolutionMode", conflictResolutionMode.toString());
// params = params.set("sendInvitationsOrCancellationsMode", sendInvitationsOrCancellationsMode.toString());
// params.set('CalendarId', event.CalendarId)
// params.set('CalendarName', event.CalendarName)
options = {
headers: header,
params: params
};
// options = {
// headers: header,
// params: params
// };
const putUrl = environment.apiURL + 'calendar/PutEvent';
return this.HttpServiceService.put<string>(`${putUrl}`, event, options);
// const putUrl = environment.apiURL + 'calendar/PutEvent';
// return this.HttpServiceService.put<string>(`${putUrl}`, event, options);
}
// }
// ================================ Acções =================================================
@@ -4,7 +4,7 @@ import { removeDuplicate } from 'src/plugin/removeDuplicate.js'
import { ThemeService } from 'src/app/services/theme.service'
import { ViewChild } from '@angular/core';
import { Searchbar } from 'ionic-angular';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { SessionStore } from 'src/app/store/session.service';
import { Router } from '@angular/router';
import { ContactRepositoryService } from 'src/app/services/Repositorys/contacts/repository/contacts-repository.service';
@@ -46,7 +46,7 @@ export class AttendeePage implements OnInit {
LtaskParticipants: EventPerson[] = [];
LtaskParticipantsCc: EventPerson[] = [];
loggeduser: LoginUserRespose;
loggeduser: UserSession;
listOfNotAllowdRoute = ['/home/gabinete-digital/despachos/', ]
selectedUserCalendar:any;
@@ -1,6 +1,6 @@
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { ThemeService } from 'src/app/services/theme.service';
import { TaskService } from 'src/app/services/task.service';
@@ -13,7 +13,7 @@ import { TaskService } from 'src/app/services/task.service';
export class AllProcessesPage implements OnInit {
skeletonLoader = false;
loggeduser: LoginUserRespose;
loggeduser: UserSession;
hideSearchBtn: boolean = false;
showSearch = false;
searchSubject: string = '';
@@ -1,6 +1,6 @@
import { Component, OnInit} from '@angular/core';
import { customTask} from '../../../models/dailyworktask.model';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { NavigationStart, Router } from '@angular/router';
import { DespachosprStore } from 'src/app/store/despachospr-store.service';
import { CustomTaskPipe } from 'src/app/pipes/custom-task.pipe';
@@ -20,7 +20,7 @@ export class DespachosPrPage implements OnInit {
customTaskPipe = new CustomTaskPipe()
skeletonLoader = false
loggeduser: LoginUserRespose;
loggeduser: UserSession;
despachosprstore = DespachosprStore;
environment = environment
filterName: 'Para hoje' | 'Novos'| 'Lidos'| 'Não lidos'| 'OverdueTasks' | 'Todos' = 'Todos'
@@ -1,7 +1,7 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { NavigationStart, Router } from '@angular/router';
import { ProcessesService } from 'src/app/services/processes.service';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { CustomTaskPipe } from 'src/app/pipes/custom-task.pipe';
import { ExpedienteGdStore } from 'src/app/store/expedientegd-store.service';
import { ExpedienteTaskPipe } from 'src/app/pipes/expediente-task.pipe';
@@ -25,7 +25,7 @@ export class ExpedientesPrPage implements OnInit {
customTaskPipe = new CustomTaskPipe()
expedienteTaskPipe = new ExpedienteTaskPipe()
loggeduser: LoginUserRespose;
loggeduser: UserSession;
filterName: 'Para hoje' | 'Novos'| 'Lidos'| 'Não lidos'| 'OverdueTasks' | 'Todos' = 'Todos'
showSearch = false
@@ -9,7 +9,7 @@ import { ModalController } from '@ionic/angular';
import { DocumentSetUpMeetingPage } from 'src/app/modals/document-set-up-meeting/document-set-up-meeting.page';
import { HeaderSettingsService } from "src/app/services/header-settings.service"
import { SessionStore } from 'src/app/store/session.service';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@@ -33,7 +33,7 @@ export class TaskDetailsPage implements OnInit {
selectedIndex = 0
dropButton = true
loggeduser: LoginUserRespose;
loggeduser: UserSession;
@ViewChild('text', { static: false }) text: ElementRef;
constructor(
@@ -48,20 +48,10 @@ export class TaskDetailsPage implements OnInit {
this.DeviceService.isDesktop();
this.loggeduser = SessionStore.user
// if(this.task.Note) {
// this.task.Note = this.sanitizeHtml(this.task.Note) as any
// }
// if(this.fulltask?.workflowInstanceDataFields?.TaskMessage) {
// this.fulltask.workflowInstanceDataFields.TaskMessage = this.sanitizeHtml(this.fulltask.workflowInstanceDataFields.TaskMessage);
// }
setTimeout(() => {
console.log('change', this.task.Note);
// this.task.Note = this.sanitizeHtml(this.task.Note) as any
if(this.text.nativeElement) {
if(this.text?.nativeElement) {
(this.text.nativeElement as HTMLDivElement).innerHTML = this.decode(this.task.Note)
}
@@ -71,7 +61,7 @@ export class TaskDetailsPage implements OnInit {
setTimeout(() => {
console.log('change', this.task.Note);
// this.task.Note = this.sanitizeHtml(this.task.Note) as any
if(this.text.nativeElement) {
if(this.text?.nativeElement) {
(this.text.nativeElement as HTMLDivElement).innerHTML = this.decode(this.task.Note)
}
@@ -80,7 +70,7 @@ export class TaskDetailsPage implements OnInit {
setTimeout(() => {
console.log('change', this.task.Note);
// this.task.Note = this.sanitizeHtml(this.task.Note) as any
if(this.text.nativeElement) {
if(this.text?.nativeElement) {
(this.text.nativeElement as HTMLDivElement).innerHTML = this.decode(this.task.Note)
}
@@ -89,7 +79,7 @@ export class TaskDetailsPage implements OnInit {
setTimeout(() => {
console.log('change', this.task.Note);
// this.task.Note = this.sanitizeHtml(this.task.Note) as any
if(this.text.nativeElement) {
if(this.text?.nativeElement) {
(this.text.nativeElement as HTMLDivElement).innerHTML = this.decode(this.task.Note)
}
@@ -98,7 +88,7 @@ export class TaskDetailsPage implements OnInit {
setTimeout(() => {
console.log('change', this.task.Note);
// this.task.Note = this.sanitizeHtml(this.task.Note) as any
if(this.text.nativeElement) {
if(this.text?.nativeElement) {
(this.text.nativeElement as HTMLDivElement).innerHTML = this.decode(this.task.Note)
}
@@ -108,7 +98,7 @@ export class TaskDetailsPage implements OnInit {
setTimeout(() => {
console.log('change', this.task.Note);
// this.task.Note = this.sanitizeHtml(this.task.Note) as any
if(this.text.nativeElement) {
if(this.text?.nativeElement) {
(this.text.nativeElement as HTMLDivElement).innerHTML = this.decode(this.task.Note)
}
@@ -185,7 +175,7 @@ export class TaskDetailsPage implements OnInit {
classs = 'modal modal-desktop showAsideOptions'
}
// check passing
console.log('this.Document----------openExpedientActionsModal', Document)
console.log('this.Document----------openExpedientActionsModal', Document, this.fulltask)
const modal = await this.modalController.create({
component: ExpedientTaskModalPage,
componentProps: {
@@ -4,7 +4,7 @@ import { removeDuplicate } from 'src/plugin/removeDuplicate.js'
import { customTask} from '../../../models/dailyworktask.model';
import { ProcessesService } from 'src/app/services/processes.service';
import { PendentesStore } from 'src/app/store/pendestes-store.service';
import { LoginUserRespose } from 'src/app/models/user.model';
import { UserSession } from 'src/app/models/user.model';
import { CustomTaskPipe } from 'src/app/pipes/custom-task.pipe';
import { SortService } from 'src/app/services/functions/sort.service';
import { Storage } from '@ionic/storage';
@@ -22,7 +22,7 @@ export class PendentesPage implements OnInit {
skeletonLoader: boolean = false;
pendentesstore = PendentesStore;
customTaskPipe = new CustomTaskPipe()
loggeduser: LoginUserRespose;
loggeduser: UserSession;
listToPresent = [];
@Input() profile:string;
@@ -26,7 +26,7 @@
</div>
<div *ngIf="task && p.userRole(['PR'])" class="d-flex width-100">
<div class="flex-grow-1">
<button *ngIf="p.userPermission([p.permissionList.Gabinete.pr_tasks])" (click)="openAddNoteModal('Concluido')" class="btn-cancel" shape="round" >Marcar como Concluído</button>
<button *ngIf="p.userPermission([p.permissionList.Gabinete.pr_tasks])" (click)="openAddNoteModal('Executado1')" class="btn-cancel" shape="round" >Marcar como Concluído</button>
<button *ngIf="p.userPermission([p.permissionList.Gabinete.pr_tasks])" (click)="openAddNoteModal('Reexecução')" class="btn-cancel" shape="round" >Enviar para Reexecução</button>
<button *ngIf="p.userPermission([p.permissionList.Agenda.access])" (click)="openBookMeetingModal(task)" class="btn-cancel" shape="round" >Marcar Reunião</button>
<button *ngIf="p.userPermission([p.permissionList.Gabinete.pr_tasks]) && task.Status != 'Pending'" (click)="sendExpedienteToPending()" class="btn-cancel" shape="round" >Enviar para Pendentes</button>

Some files were not shown because too many files have changed in this diff Show More