Skip to content

Commit

Permalink
Merge pull request #17686 from ckeditor/ck/17531
Browse files Browse the repository at this point in the history
Fix (cloud-services): No longer keep refreshing token if tokenUrl method failed in the initialization of the plugin. Closes #17531
  • Loading branch information
Mati365 authored Dec 30, 2024
2 parents c5143d0 + 84cd346 commit 4896a62
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
18 changes: 14 additions & 4 deletions packages/ckeditor5-cloud-services/src/cloudservices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,21 @@ export default class CloudServices extends ContextPlugin implements CloudService
return;
}

// Initialization of the token may fail. By default, the token is being refreshed on the failure.
// The problem is that if this happens here, then the token refresh interval will be executed even
// after destroying the editor (as the exception was thrown from `init` method). To prevent that
// behavior we need to catch the exception and destroy the uninitialized token instance.
// See: https://github.com/ckeditor/ckeditor5/issues/17531
const cloudServicesCore: CloudServicesCore = this.context.plugins.get( 'CloudServicesCore' );

this.token = await cloudServicesCore.createToken( this.tokenUrl ).init();

this._tokens.set( this.tokenUrl, this.token );
const uninitializedToken = cloudServicesCore.createToken( this.tokenUrl );

try {
this.token = await uninitializedToken.init();
this._tokens.set( this.tokenUrl, this.token );
} catch ( error ) {
uninitializedToken.destroy();
throw error;
}
}

/**
Expand Down
31 changes: 30 additions & 1 deletion packages/ckeditor5-cloud-services/tests/cloudservices.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/

/* global document */
/* global document, console */

import CloudServices from '../src/cloudservices.js';
import CloudServicesCore from '../src/cloudservicescore.js';
Expand Down Expand Up @@ -170,6 +170,35 @@ describe( 'CloudServices', () => {
return context.destroy();
} );
} );

it( 'if token url crashes, then it should not create infinity loop of requests after destroy of the editor', async () => {
const clock = sinon.useFakeTimers();

sinon.stub( console, 'warn' );

const tokenUrlStub = sinon.stub().rejects( new Error( 'Token URL crashed' ) );

try {
await Context.create( {
plugins: [ CloudServices ],
cloudServices: {
tokenUrl: tokenUrlStub
}
} );

expect.fail( 'Context.create should reject' );
} catch ( error ) {
expect( error.message ).to.equal( 'Token URL crashed' );
}

expect( tokenUrlStub ).to.be.calledOnce;

clock.tick( 17000 );
clock.restore();

// Editor was destroyed at this moment, so no more requests should be made.
expect( tokenUrlStub ).to.be.calledOnce;
} );
} );

describe( 'registerTokenUrl()', () => {
Expand Down

0 comments on commit 4896a62

Please sign in to comment.