From daefe97735da016e4afd7e0bc9b3fb524a57e084 Mon Sep 17 00:00:00 2001 From: xinhyao <142190897+xinhyao@users.noreply.github.com> Date: Sun, 1 Dec 2024 06:27:43 +0800 Subject: [PATCH] fix(automotive): qr code for launching webex app (#4012) --- .../src/authorization.js | 27 ++++++++++++++- .../test/unit/spec/authorization.js | 34 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/packages/@webex/plugin-authorization-browser-first-party/src/authorization.js b/packages/@webex/plugin-authorization-browser-first-party/src/authorization.js index 381b63c037d..91be8a7ce34 100644 --- a/packages/@webex/plugin-authorization-browser-first-party/src/authorization.js +++ b/packages/@webex/plugin-authorization-browser-first-party/src/authorization.js @@ -295,6 +295,30 @@ const Authorization = WebexPlugin.extend({ }); }, + /** + * Generate a QR code URL to launch the Webex app when scanning with the camera + * @instance + * @memberof AuthorizationBrowserFirstParty + * @param {String} verificationUrl + * @returns {String} + */ + _generateQRCodeVerificationUrl(verificationUrl) { + const baseUrl = 'https://web.webex.com/deviceAuth'; + const urlParams = new URLSearchParams(new URL(verificationUrl).search); + const userCode = urlParams.get('userCode'); + + if (userCode) { + const {services} = this.webex.internal; + const oauthHelperUrl = services.get('oauth-helper'); + const newVerificationUrl = new URL(baseUrl); + newVerificationUrl.searchParams.set('usercode', userCode); + newVerificationUrl.searchParams.set('oauthhelper', oauthHelperUrl); + return newVerificationUrl.toString(); + } else { + return verificationUrl; + } + }, + /** * Get an OAuth Login URL for QRCode. Generate QR code based on the returned URL. * @instance @@ -327,12 +351,13 @@ const Authorization = WebexPlugin.extend({ }) .then((res) => { const {user_code, verification_uri, verification_uri_complete} = res.body; + const verificationUriComplete = this._generateQRCodeVerificationUrl(verification_uri_complete); this.eventEmitter.emit(Events.qRCodeLogin, { eventType: 'getUserCodeSuccess', userData: { userCode: user_code, verificationUri: verification_uri, - verificationUriComplete: verification_uri_complete, + verificationUriComplete, }, }); // if device authorization success, then start to poll server to check whether the user has completed authorization diff --git a/packages/@webex/plugin-authorization-browser-first-party/test/unit/spec/authorization.js b/packages/@webex/plugin-authorization-browser-first-party/test/unit/spec/authorization.js index 26709ca3da2..b08af627998 100644 --- a/packages/@webex/plugin-authorization-browser-first-party/test/unit/spec/authorization.js +++ b/packages/@webex/plugin-authorization-browser-first-party/test/unit/spec/authorization.js @@ -443,6 +443,38 @@ describe('plugin-authorization-browser-first-party', () => { }); }); + describe('#_generateQRCodeVerificationUrl()', () => { + it('should generate a QR code URL when a userCode is present', () => { + const verificationUrl = 'https://example.com/verify?userCode=123456'; + const oauthHelperUrl = 'https://oauth-helper-a.wbx2.com/helperservice/v1'; + const expectedUrl = 'https://web.webex.com/deviceAuth?usercode=123456&oauthhelper=https%3A%2F%2Foauth-helper-a.wbx2.com%2Fhelperservice%2Fv1'; + + const webex = makeWebex('http://example.com'); + + const oauthHelperSpy = sinon.stub(webex.internal.services, 'get').returns(oauthHelperUrl); + const result = webex.authorization._generateQRCodeVerificationUrl(verificationUrl); + + assert.calledOnce(oauthHelperSpy); + assert.calledWithExactly(oauthHelperSpy, 'oauth-helper'); + assert.equal(result, expectedUrl); + + oauthHelperSpy.restore(); + }); + + it('should return the original verificationUrl when userCode is not present', () => { + const verificationUrl = 'https://example.com/verify'; + const webex = makeWebex('http://example.com'); + + const oauthHelperSpy = sinon.stub(webex.internal.services, 'get'); + const result = webex.authorization._generateQRCodeVerificationUrl(verificationUrl); + + assert.notCalled(oauthHelperSpy); + assert.equal(result, verificationUrl); + + oauthHelperSpy.restore(); + }); + }); + describe('#initQRCodeLogin()', () => { it('should prevent concurrent request if there is already a polling request', async () => { const webex = makeWebex('http://example.com'); @@ -477,6 +509,7 @@ describe('plugin-authorization-browser-first-party', () => { }); webex.request.onFirstCall().resolves({statusCode: 200, body: sampleData}); sinon.spy(webex.authorization, '_startQRCodePolling'); + sinon.spy(webex.authorization, '_generateQRCodeVerificationUrl'); const emitSpy = sinon.spy(webex.authorization.eventEmitter, 'emit'); webex.authorization.initQRCodeLogin(); @@ -485,6 +518,7 @@ describe('plugin-authorization-browser-first-party', () => { assert.calledTwice(webex.request); assert.calledOnce(webex.authorization._startQRCodePolling); + assert.calledOnce(webex.authorization._generateQRCodeVerificationUrl); assert.equal(emitSpy.getCall(0).args[1].eventType, 'getUserCodeSuccess'); const request = webex.request.getCall(0);