diff --git a/src/app/entities/user.ts b/src/app/entities/user.ts index 62b3185..2226e1b 100644 --- a/src/app/entities/user.ts +++ b/src/app/entities/user.ts @@ -1,3 +1,5 @@ +import { UserDataResult } from 'angular-auth-oidc-client'; + export type UserId = string; export class User { @@ -8,17 +10,18 @@ export class User { public name: string, public admin: boolean = false ) { } - - static fromClaims(claims: object): User { - if (claims == null) { - return null; - } - return new User( - claims["sub"].toString(), - claims["preferred_username"].toString(), - '@' + claims["preferred_username"] + ':okupamicoche-synapse', - claims["name"].toString(), - claims["admin"] === true - ); - } } + +export const userFromClaims = (claims: UserDataResult) => { + if (claims === null || claims.userData === null) { + return null; + } + + return new User( + claims.userData["sub"], + claims.userData["preferred_username"], + '@' + claims["preferred_username"] + ':okupamicoche-synapse', + claims.userData["name"], + claims.userData["admin"] === true + ); +} \ No newline at end of file diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index 5a3714c..0ccf6fe 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { BehaviorSubject } from 'rxjs'; -import { User } from '../entities/user'; +import { OidcSecurityService, UserDataResult } from 'angular-auth-oidc-client'; +import { BehaviorSubject, firstValueFrom } from 'rxjs'; +import { User, userFromClaims } from '../entities/user'; import { ApiService } from './api.service'; import { ChatService } from './chat.service'; @@ -41,46 +41,54 @@ export class AuthService { async configureAndTryLogin(chatLoginToken: string): Promise { this.oidcSecurityService.isAuthenticated$.subscribe((authenticatedResult) => { - console.log('isAuthenticated', authenticatedResult); + console.log('isAuthenticated', authenticatedResult.isAuthenticated); this.loggedSubject.next(authenticatedResult.isAuthenticated); }); - this.oidcSecurityService.userData$.subscribe((claims) => { - if (claims != null) { - console.log(User.fromClaims(claims)); - } - this.userSubject.next(User.fromClaims(claims)); + this.oidcSecurityService.userData$.subscribe((claims: UserDataResult) => { + console.log('claims', userFromClaims(claims)); + this.userSubject.next(userFromClaims(claims)); }); - return this.oidcSecurityService.checkAuth().toPromise().then(async (auth) => { - console.log('AUTH INITIALIZED result=', auth); + return firstValueFrom(this.oidcSecurityService.checkAuth()) + .then(async (auth) => { + console.log('AUTH INITIALIZED isAuthenticated=', auth.isAuthenticated); - if (auth) { - if (sessionStorage.getItem('chatLoginInProcess') === 'true') { - sessionStorage.removeItem('chatLoginInProcess'); + if (auth.isAuthenticated) { - if (chatLoginToken) { - console.log('chatLoginToken=' + chatLoginToken); - await this.chatService.login(chatLoginToken); + + + + console.log('AUTH INITIALIZED result=', auth); + this.apiService.getUser().subscribe(res => console.log(res)); + return AuthState.Logged; + + + if (sessionStorage.getItem('chatLoginInProcess') === 'true') { + sessionStorage.removeItem('chatLoginInProcess'); + + if (chatLoginToken) { + console.log('chatLoginToken=' + chatLoginToken); + await this.chatService.login(chatLoginToken); + } + else { + console.error('CHAT LOGIN TOKEN NOT RECEIVED'); + } + + // Endpoint /user/ creates User in DB if it does not exist + this.apiService.getUser().subscribe(res => console.log(res)); + + return AuthState.Logged; } else { - console.error('CHAT LOGIN TOKEN NOT RECEIVED'); + console.log('GO TO SSO LOGIN'); + sessionStorage.setItem('chatLoginInProcess', 'true'); + this.chatService.goToSsoLogin(); + return AuthState.ChatLoggingInProcess; } - - // Endpoint /user/ creates User in DB if it does not exist - this.apiService.getUser().subscribe(res => console.log(res)); - - return AuthState.Logged; } - else { - console.log('GO TO SSO LOGIN'); - sessionStorage.setItem('chatLoginInProcess', 'true'); - this.chatService.goToSsoLogin(); - return AuthState.ChatLoggingInProcess; - } - } - return AuthState.NotLogged; - }); + return AuthState.NotLogged; + }); } } diff --git a/src/app/services/chat-message-handler.ts b/src/app/services/chat-message-handler.ts index 3ed5f13..f295824 100644 --- a/src/app/services/chat-message-handler.ts +++ b/src/app/services/chat-message-handler.ts @@ -1,4 +1,4 @@ -import { EventTimeline, MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk'; +import { MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk'; import { Subject } from 'rxjs'; export class ChatMessageHandler { @@ -6,11 +6,10 @@ export class ChatMessageHandler { private matrixClientPromise: Promise, ) { } - getRoomMessages = (roomId: string): Subject => { - const subject = new Subject(); + getRoomMessages = (roomId: string): Subject => { + const subject = new Subject(); - // TODO - // this.publishRoomOldMessages(roomId, subject); + this.publishRoomOldMessages(roomId, subject); this.publishRoomNewMessages(roomId, subject); return subject; @@ -25,22 +24,21 @@ export class ChatMessageHandler { }); } - private publishRoomNewMessages(roomId: string, subject: Subject): void { + private publishRoomNewMessages(roomId: string, subject: Subject): void { this.matrixClientPromise.then(client => { - // TODO - // client.on('Room.timeline', (event: EventTimeline, room: Room, toStartOfTimeline: boolean) => { - // if (room.roomId !== roomId) { - // return; // only listen to specified room - // } - // if (toStartOfTimeline) { - // return; // don't print paginated results - // } - // if (event.getType() !== 'm.room.message') { - // return; // only print messages - // } + client.on('Room.timeline', (event: MatrixEvent, room: Room, toStartOfTimeline: boolean) => { + if (room.roomId !== roomId) { + return; // only listen to specified room + } + if (toStartOfTimeline) { + return; // don't print paginated results + } + if (event.getType() !== 'm.room.message') { + return; // only print messages + } - // subject.next(event); - // }); + subject.next(event); + }); }); } } diff --git a/src/app/services/chat.service.ts b/src/app/services/chat.service.ts index e2a2383..0de9840 100644 --- a/src/app/services/chat.service.ts +++ b/src/app/services/chat.service.ts @@ -1,9 +1,9 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; +import { createClient, ICreateClientOpts, ISendEventResponse, MatrixClient, MatrixEvent, Room, RoomMember } from 'matrix-js-sdk'; +import { firstValueFrom, Observable } from 'rxjs'; import { MatrixLoginDto } from '../entities/matrix-login-dto'; import { ChatMessageHandler } from './chat-message-handler'; -import { MatrixEvent, MatrixClient, Room, RoomMember, createClient, EventTimeline, ISendEventResponse, ICreateClientOpts } from 'matrix-js-sdk'; const FORWARDS = 'f'; @@ -14,7 +14,7 @@ export class ChatService { private matrixClient: MatrixClient; private chatMessageHandler: ChatMessageHandler; - getRoomMessages: (roomId: string) => (Observable); + getRoomMessages: (roomId: string) => (Observable); constructor( private http: HttpClient @@ -89,20 +89,19 @@ export class ChatService { } catch (error) { return true; } } - // const joinRule = room.currentState.getJoinRule(); - const joinRule = 'invite'; // TODO + const joinRule = room.currentState.getJoinRule(); return joinRule === 'invite'; } private async loginWithToken(loginToken: string): Promise { - const matrixLogin = await this.http.post( + const matrixLogin = await firstValueFrom(this.http.post( 'http://okupamicoche-synapse:8008/_matrix/client/r0/login', { initial_device_display_name: 'Okupa mi coche', token: loginToken, type: 'm.login.token' } - ).toPromise(); + )); console.log('LOGGED TO CHAT'); console.log({ matrixLogin }); const ops: ICreateClientOpts = { @@ -114,14 +113,13 @@ export class ChatService { await this.matrixClient.startClient({ initialSyncLimit: 100 }); - // TODO - // this.matrixClient.once('sync', (state: string, prevState: string, _: any) => { - // if (state === 'PREPARED') { - // console.log('CHAT SYNC FINISHED'); - // } else { - // console.log('MATRIX CLIENT STATE CHANGED state=' + state); - // } - // }); + this.matrixClient.once('sync', (state: string, prevState: string, _: any) => { + if (state === 'PREPARED') { + console.log('CHAT SYNC FINISHED'); + } else { + console.log('MATRIX CLIENT STATE CHANGED state=' + state); + } + }); return this.matrixClient; } diff --git a/src/app/views/chat/chat.component.ts b/src/app/views/chat/chat.component.ts index cde354c..d066a50 100644 --- a/src/app/views/chat/chat.component.ts +++ b/src/app/views/chat/chat.component.ts @@ -1,5 +1,5 @@ import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core'; -import { EventTimeline, RoomMember } from 'matrix-js-sdk'; +import { MatrixEvent, RoomMember } from 'matrix-js-sdk'; import { ChatService } from 'src/app/services/chat.service'; @Component({ @@ -11,7 +11,7 @@ export class ChatComponent implements OnInit, AfterViewInit { @Input() roomId: string; @ViewChild('messageList', { read: ElementRef }) messageList: ElementRef; @ViewChildren('messageItem', { read: ElementRef }) messageItems: QueryList; - messages: EventTimeline[] = new Array(); + messages: MatrixEvent[] = new Array(); messageInput: string; constructor( @@ -24,7 +24,7 @@ export class ChatComponent implements OnInit, AfterViewInit { const messages$ = this.chatService.getRoomMessages(this.roomId); messages$.subscribe({ - next: (event: EventTimeline) => { + next: (event: MatrixEvent) => { this.messages.push(event); this.changeDetection.detectChanges(); // TODO theoretically it is not needed }