diff --git a/lib/js-api/src/alfrescoApi.ts b/lib/js-api/src/alfrescoApi.ts index bee57b4e3e..f7cf9c4f32 100644 --- a/lib/js-api/src/alfrescoApi.ts +++ b/lib/js-api/src/alfrescoApi.ts @@ -79,6 +79,7 @@ export class AlfrescoApi implements Emitter, AlfrescoApiType { this.clientsFactory(); this.errorListeners(); + this.ticketMismatchListeners(); if (this.config.oauthInit) { this.initAuth(config); @@ -132,6 +133,10 @@ export class AlfrescoApi implements Emitter, AlfrescoApiType { this.emitBuffer('logged-in'); }); + this.processAuth?.on('ticket_mismatch', (error: any) => { + this.ticketMismatchHandler(error); + }); + if (!this.contentAuth) { this.contentAuth = new ContentAuth(this.config, this, this.httpClient); } else { @@ -142,6 +147,10 @@ export class AlfrescoApi implements Emitter, AlfrescoApiType { this.emitBuffer('logged-in'); }); + this.contentAuth?.on('ticket_mismatch', (error: any) => { + this.ticketMismatchHandler(error); + }); + this.setAuthenticationClientECMBPM(this.contentAuth.getAuthentication(), this.processAuth.getAuthentication()); } } @@ -240,6 +249,19 @@ export class AlfrescoApi implements Emitter, AlfrescoApiType { }); } + ticketMismatchListeners() { + this.contentClient?.off('ticket_mismatch', () => {}); + this.processClient?.off('ticket_mismatch', () => {}); + + this.contentClient?.on('ticket_mismatch', (error: any) => { + this.ticketMismatchHandler(error); + }); + + this.processClient?.on('ticket_mismatch', (error: any) => { + this.ticketMismatchHandler(error); + }); + } + /**@private? */ errorHandler(error: { status?: number }) { if (this.config.oauthInit && error.status === 401) { @@ -249,6 +271,15 @@ export class AlfrescoApi implements Emitter, AlfrescoApiType { this.emitBuffer('error', error); } + ticketMismatchHandler(error: { newTicket?: string }) { + if (error.newTicket) { + this.config.ticketEcm = error.newTicket; + this.initConfig(this.config); + } + + this.emitBuffer('ticket_mismatch', error); + } + changeWithCredentialsConfig(withCredentials: boolean) { this.config.withCredentials = withCredentials; } diff --git a/lib/js-api/src/alfrescoApiClient.ts b/lib/js-api/src/alfrescoApiClient.ts index ba956f8ca1..e3b4edc19f 100644 --- a/lib/js-api/src/alfrescoApiClient.ts +++ b/lib/js-api/src/alfrescoApiClient.ts @@ -243,10 +243,18 @@ export class AlfrescoApiClient implements ee.Emitter, LegacyHttpClient { if (ticket) { return ticketParam + ticket; - } else if (this.config.ticketEcm) { - return ticketParam + this.config.ticketEcm; - } else if (this.storage.getItem('ticket-ECM')) { - return ticketParam + this.storage.getItem('ticket-ECM'); + } else { + const ticketConfig = this.config.ticketEcm; + const ticketStorage = this.storage.getItem('ticket-ECM'); + + if (ticketConfig && ticketStorage && ticketConfig !== ticketStorage) { + this.emit('ticket_mismatch', { newTicket: ticketStorage }); + return ticketParam + ticketStorage; + } else if (ticketConfig) { + return ticketParam + ticketConfig; + } else if (ticketStorage) { + return ticketParam + ticketStorage; + } } return ''; diff --git a/lib/js-api/test/alfrescoApi.spec.ts b/lib/js-api/test/alfrescoApi.spec.ts index 20e3a88273..dfa7eb99b6 100644 --- a/lib/js-api/test/alfrescoApi.spec.ts +++ b/lib/js-api/test/alfrescoApi.spec.ts @@ -62,6 +62,39 @@ describe('Basic configuration test', () => { }); }); + describe('ticket mismatch', () => { + it('should update config ticketEcm on ticket_mismatch event', (done) => { + // Tickets + const mockStorageTicket = 'storage-ticket'; + const mockConfigTicket = 'config-ticket'; + + // Create a mock storage + const storageContent = { 'ticket-ECM': mockStorageTicket }; + const mockStorage = { getItem: (key: string) => storageContent[key] }; + + // Initialize AlfrescoApi instance (without ticketEcm to prevent validateTicket from being called at this point) + const alfrescoApi = new AlfrescoApi({ authType: 'BASIC' }); + + // Initializes configuration and storage + alfrescoApi.config.ticketEcm = mockConfigTicket; + alfrescoApi.contentClient.config.ticketEcm = mockConfigTicket; + alfrescoApi.contentClient.storage = mockStorage as any; + + // Ensure alfrescoApi and contentClient have the config ticket + assert.equal(alfrescoApi.config.ticketEcm, mockConfigTicket); + assert.equal(alfrescoApi.contentClient.config.ticketEcm, mockConfigTicket); + + alfrescoApi.on('ticket_mismatch', () => { + // As the ticket mismatch event is triggered, the ticketEcm should now be the one from storage + assert.equal(alfrescoApi.config.ticketEcm, mockStorageTicket); + assert.equal(alfrescoApi.contentClient.config.ticketEcm, mockStorageTicket); + done(); + }); + + alfrescoApi.contentClient.getAlfTicket(undefined); + }); + }); + describe('setconfig parameter ', () => { it('should be possible change the host in the client', () => { const config = { diff --git a/lib/js-api/test/alfrescoApiClient.spec.ts b/lib/js-api/test/alfrescoApiClient.spec.ts index b7344b62f1..28d097b386 100644 --- a/lib/js-api/test/alfrescoApiClient.spec.ts +++ b/lib/js-api/test/alfrescoApiClient.spec.ts @@ -16,7 +16,7 @@ */ import assert from 'assert'; -import { AlfrescoApi, DateAlfresco } from '../src'; +import { AlfrescoApi, AlfrescoApiClient, DateAlfresco } from '../src'; import { EcmAuthMock } from './mockObjects'; describe('Alfresco Core API Client', () => { @@ -76,4 +76,37 @@ describe('Alfresco Core API Client', () => { assert.equal(equalTime(DateAlfresco.parseDate('2015-11-17T03:33:17+02'), new Date(Date.UTC(2015, 10, 17, 1, 33, 17))), true); }); }); + + describe('Alfresco Api Client getAlfTicket', () => { + // Tickets + const alfTicketParam = '&alf_ticket='; + const mockArgTicket = 'arg-ticket'; + const mockStorageTicket = 'storage-ticket'; + const mockConfigTicket = 'config-ticket'; + + // Create a mock storage + const storageContent = { 'ticket-ECM': mockStorageTicket }; + const mockStorage = { getItem: (key: string) => storageContent[key] }; + + let alfrescoApiClient: AlfrescoApiClient; + + beforeEach(() => { + // Create an instance of AlfrescoApiClient with storage and config + alfrescoApiClient = new AlfrescoApiClient(); + alfrescoApiClient.storage = mockStorage as any; + alfrescoApiClient.config = { ticketEcm: mockConfigTicket }; + }); + + it('should return the supplied ticket', () => { + const ticket = alfrescoApiClient.getAlfTicket(mockArgTicket); + const expectedResult = alfTicketParam + mockArgTicket; + assert.equal(ticket, expectedResult); + }); + + it('should return the ticket from storage', () => { + const ticket = alfrescoApiClient.getAlfTicket(undefined); + const expectedResult = alfTicketParam + mockStorageTicket; + assert.equal(ticket, expectedResult); + }); + }); });