From bb806b6ee01814de18852fd6b6c6fe1ba1322bd5 Mon Sep 17 00:00:00 2001 From: Stefan Becker <586690+snacker81@users.noreply.github.com> Date: Tue, 1 Sep 2026 06:41:53 +0200 Subject: [PATCH 1/3] Social login improvements --- packages/web-core/openapi/spec_v2.yaml | 8 ++++ packages/web-core/src/api/v2/api.ts | 41 ++++++++++++------- .../web-core/src/services/ProcessService.ts | 22 +++++++++- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/packages/web-core/openapi/spec_v2.yaml b/packages/web-core/openapi/spec_v2.yaml index b82b2cca..af25fa90 100644 --- a/packages/web-core/openapi/spec_v2.yaml +++ b/packages/web-core/openapi/spec_v2.yaml @@ -1335,6 +1335,14 @@ components: socialVerifyFinishReq: type: object + required: + - code + properties: + code: + type: string + description: >- + One-time code delivered to the initiating browser via the social callback redirect. It binds the + finish to the browser that authenticated with the provider and is required to complete the login. ssoSaml2StartReq: type: object diff --git a/packages/web-core/src/api/v2/api.ts b/packages/web-core/src/api/v2/api.ts index 06463221..cfbc557e 100644 --- a/packages/web-core/src/api/v2/api.ts +++ b/packages/web-core/src/api/v2/api.ts @@ -3142,6 +3142,19 @@ export const SocialProviderType = { export type SocialProviderType = typeof SocialProviderType[keyof typeof SocialProviderType]; +/** + * + * @export + * @interface SocialVerifyFinishReq + */ +export interface SocialVerifyFinishReq { + /** + * One-time code delivered to the initiating browser via the social callback redirect. It binds the finish to the browser that authenticated with the provider and is required to complete the login. + * @type {string} + * @memberof SocialVerifyFinishReq + */ + 'code': string; +} /** * * @export @@ -3995,13 +4008,13 @@ export const AuthApiAxiosParamCreator = function (configuration?: Configuration) /** * Completes the social authentication verification process. * @summary Finish social verification - * @param {object} body + * @param {SocialVerifyFinishReq} socialVerifyFinishReq * @param {*} [options] Override http request option. * @throws {RequiredError} */ - socialVerifyFinish: async (body: object, options: AxiosRequestConfig = {}): Promise => { - // verify required parameter 'body' is not null or undefined - assertParamExists('socialVerifyFinish', 'body', body) + socialVerifyFinish: async (socialVerifyFinishReq: SocialVerifyFinishReq, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'socialVerifyFinishReq' is not null or undefined + assertParamExists('socialVerifyFinish', 'socialVerifyFinishReq', socialVerifyFinishReq) const localVarPath = `/v2/auth/social/verify/finish`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); @@ -4028,7 +4041,7 @@ export const AuthApiAxiosParamCreator = function (configuration?: Configuration) setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(body, localVarRequestOptions, configuration) + localVarRequestOptions.data = serializeDataIfNeeded(socialVerifyFinishReq, localVarRequestOptions, configuration) return { url: toPathString(localVarUrlObj), @@ -4382,12 +4395,12 @@ export const AuthApiFp = function(configuration?: Configuration) { /** * Completes the social authentication verification process. * @summary Finish social verification - * @param {object} body + * @param {SocialVerifyFinishReq} socialVerifyFinishReq * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async socialVerifyFinish(body: object, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.socialVerifyFinish(body, options); + async socialVerifyFinish(socialVerifyFinishReq: SocialVerifyFinishReq, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.socialVerifyFinish(socialVerifyFinishReq, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -4612,12 +4625,12 @@ export const AuthApiFactory = function (configuration?: Configuration, basePath? /** * Completes the social authentication verification process. * @summary Finish social verification - * @param {object} body + * @param {SocialVerifyFinishReq} socialVerifyFinishReq * @param {*} [options] Override http request option. * @throws {RequiredError} */ - socialVerifyFinish(body: object, options?: any): AxiosPromise { - return localVarFp.socialVerifyFinish(body, options).then((request) => request(axios, basePath)); + socialVerifyFinish(socialVerifyFinishReq: SocialVerifyFinishReq, options?: any): AxiosPromise { + return localVarFp.socialVerifyFinish(socialVerifyFinishReq, options).then((request) => request(axios, basePath)); }, /** * Initiates the social authentication verification process. @@ -4874,13 +4887,13 @@ export class AuthApi extends BaseAPI { /** * Completes the social authentication verification process. * @summary Finish social verification - * @param {object} body + * @param {SocialVerifyFinishReq} socialVerifyFinishReq * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AuthApi */ - public socialVerifyFinish(body: object, options?: AxiosRequestConfig) { - return AuthApiFp(this.configuration).socialVerifyFinish(body, options).then((request) => request(this.axios, this.basePath)); + public socialVerifyFinish(socialVerifyFinishReq: SocialVerifyFinishReq, options?: AxiosRequestConfig) { + return AuthApiFp(this.configuration).socialVerifyFinish(socialVerifyFinishReq, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/packages/web-core/src/services/ProcessService.ts b/packages/web-core/src/services/ProcessService.ts index 792d2f61..c730bba9 100644 --- a/packages/web-core/src/services/ProcessService.ts +++ b/packages/web-core/src/services/ProcessService.ts @@ -551,7 +551,27 @@ export class ProcessService { } finishSocialVerification(abortController: AbortController): Promise> { - return this.wrapWithErr(() => this.#authApi.socialVerifyFinish({}, { signal: abortController.signal })); + const code = this.#consumeSocialFinishCodeFromUrl(); + + return this.wrapWithErr(() => this.#authApi.socialVerifyFinish({ code }, { signal: abortController.signal })); + } + + #consumeSocialFinishCodeFromUrl(): string { + try { + const params = new URLSearchParams(window.location.search); + const code = params.get('corbadoSocialCode') ?? ''; + + if (code) { + params.delete('corbadoSocialCode'); + const query = params.toString(); + const newUrl = `${window.location.pathname}${query ? `?${query}` : ''}${window.location.hash}`; + window.history.replaceState(window.history.state, '', newUrl); + } + + return code; + } catch { + return ''; + } } async appendPasskey( From caed3ed73410304ff9efca086e9964b0420ac07b Mon Sep 17 00:00:00 2001 From: Stefan Becker <586690+snacker81@users.noreply.github.com> Date: Tue, 1 Sep 2026 16:19:23 +0200 Subject: [PATCH 2/3] Revert web-core social finish code approach Social hardening moved to backend IP binding, which needs no SDK change. Restores spec_v2.yaml, api/v2 client, and ProcessService.finishSocialVerification to the pre-code state (empty socialVerifyFinishReq, socialVerifyFinish({})), matching the backend contract. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01TfejXAugyze8GKHYQYZ6Ev --- packages/web-core/openapi/spec_v2.yaml | 8 ---- packages/web-core/src/api/v2/api.ts | 41 +++++++------------ .../web-core/src/services/ProcessService.ts | 22 +--------- 3 files changed, 15 insertions(+), 56 deletions(-) diff --git a/packages/web-core/openapi/spec_v2.yaml b/packages/web-core/openapi/spec_v2.yaml index af25fa90..b82b2cca 100644 --- a/packages/web-core/openapi/spec_v2.yaml +++ b/packages/web-core/openapi/spec_v2.yaml @@ -1335,14 +1335,6 @@ components: socialVerifyFinishReq: type: object - required: - - code - properties: - code: - type: string - description: >- - One-time code delivered to the initiating browser via the social callback redirect. It binds the - finish to the browser that authenticated with the provider and is required to complete the login. ssoSaml2StartReq: type: object diff --git a/packages/web-core/src/api/v2/api.ts b/packages/web-core/src/api/v2/api.ts index cfbc557e..06463221 100644 --- a/packages/web-core/src/api/v2/api.ts +++ b/packages/web-core/src/api/v2/api.ts @@ -3142,19 +3142,6 @@ export const SocialProviderType = { export type SocialProviderType = typeof SocialProviderType[keyof typeof SocialProviderType]; -/** - * - * @export - * @interface SocialVerifyFinishReq - */ -export interface SocialVerifyFinishReq { - /** - * One-time code delivered to the initiating browser via the social callback redirect. It binds the finish to the browser that authenticated with the provider and is required to complete the login. - * @type {string} - * @memberof SocialVerifyFinishReq - */ - 'code': string; -} /** * * @export @@ -4008,13 +3995,13 @@ export const AuthApiAxiosParamCreator = function (configuration?: Configuration) /** * Completes the social authentication verification process. * @summary Finish social verification - * @param {SocialVerifyFinishReq} socialVerifyFinishReq + * @param {object} body * @param {*} [options] Override http request option. * @throws {RequiredError} */ - socialVerifyFinish: async (socialVerifyFinishReq: SocialVerifyFinishReq, options: AxiosRequestConfig = {}): Promise => { - // verify required parameter 'socialVerifyFinishReq' is not null or undefined - assertParamExists('socialVerifyFinish', 'socialVerifyFinishReq', socialVerifyFinishReq) + socialVerifyFinish: async (body: object, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'body' is not null or undefined + assertParamExists('socialVerifyFinish', 'body', body) const localVarPath = `/v2/auth/social/verify/finish`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); @@ -4041,7 +4028,7 @@ export const AuthApiAxiosParamCreator = function (configuration?: Configuration) setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; - localVarRequestOptions.data = serializeDataIfNeeded(socialVerifyFinishReq, localVarRequestOptions, configuration) + localVarRequestOptions.data = serializeDataIfNeeded(body, localVarRequestOptions, configuration) return { url: toPathString(localVarUrlObj), @@ -4395,12 +4382,12 @@ export const AuthApiFp = function(configuration?: Configuration) { /** * Completes the social authentication verification process. * @summary Finish social verification - * @param {SocialVerifyFinishReq} socialVerifyFinishReq + * @param {object} body * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async socialVerifyFinish(socialVerifyFinishReq: SocialVerifyFinishReq, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.socialVerifyFinish(socialVerifyFinishReq, options); + async socialVerifyFinish(body: object, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.socialVerifyFinish(body, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -4625,12 +4612,12 @@ export const AuthApiFactory = function (configuration?: Configuration, basePath? /** * Completes the social authentication verification process. * @summary Finish social verification - * @param {SocialVerifyFinishReq} socialVerifyFinishReq + * @param {object} body * @param {*} [options] Override http request option. * @throws {RequiredError} */ - socialVerifyFinish(socialVerifyFinishReq: SocialVerifyFinishReq, options?: any): AxiosPromise { - return localVarFp.socialVerifyFinish(socialVerifyFinishReq, options).then((request) => request(axios, basePath)); + socialVerifyFinish(body: object, options?: any): AxiosPromise { + return localVarFp.socialVerifyFinish(body, options).then((request) => request(axios, basePath)); }, /** * Initiates the social authentication verification process. @@ -4887,13 +4874,13 @@ export class AuthApi extends BaseAPI { /** * Completes the social authentication verification process. * @summary Finish social verification - * @param {SocialVerifyFinishReq} socialVerifyFinishReq + * @param {object} body * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof AuthApi */ - public socialVerifyFinish(socialVerifyFinishReq: SocialVerifyFinishReq, options?: AxiosRequestConfig) { - return AuthApiFp(this.configuration).socialVerifyFinish(socialVerifyFinishReq, options).then((request) => request(this.axios, this.basePath)); + public socialVerifyFinish(body: object, options?: AxiosRequestConfig) { + return AuthApiFp(this.configuration).socialVerifyFinish(body, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/packages/web-core/src/services/ProcessService.ts b/packages/web-core/src/services/ProcessService.ts index c730bba9..792d2f61 100644 --- a/packages/web-core/src/services/ProcessService.ts +++ b/packages/web-core/src/services/ProcessService.ts @@ -551,27 +551,7 @@ export class ProcessService { } finishSocialVerification(abortController: AbortController): Promise> { - const code = this.#consumeSocialFinishCodeFromUrl(); - - return this.wrapWithErr(() => this.#authApi.socialVerifyFinish({ code }, { signal: abortController.signal })); - } - - #consumeSocialFinishCodeFromUrl(): string { - try { - const params = new URLSearchParams(window.location.search); - const code = params.get('corbadoSocialCode') ?? ''; - - if (code) { - params.delete('corbadoSocialCode'); - const query = params.toString(); - const newUrl = `${window.location.pathname}${query ? `?${query}` : ''}${window.location.hash}`; - window.history.replaceState(window.history.state, '', newUrl); - } - - return code; - } catch { - return ''; - } + return this.wrapWithErr(() => this.#authApi.socialVerifyFinish({}, { signal: abortController.signal })); } async appendPasskey( From c630f9ac7d24d8bda90497583c77e57cd77903e7 Mon Sep 17 00:00:00 2001 From: Stefan Becker <586690+snacker81@users.noreply.github.com> Date: Tue, 1 Sep 2026 17:16:26 +0200 Subject: [PATCH 3/3] Upgraded packages --- package-lock.json | 2 +- packages/web-core/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e402efe0..478436b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29176,7 +29176,7 @@ }, "packages/web-core": { "name": "@corbado/web-core", - "version": "3.7.0-alpha.2", + "version": "3.7.0-alpha.3", "license": "ISC", "dependencies": { "@corbado/webauthn-json": "^2.2.0", diff --git a/packages/web-core/package.json b/packages/web-core/package.json index e94f9771..71c5c793 100644 --- a/packages/web-core/package.json +++ b/packages/web-core/package.json @@ -1,6 +1,6 @@ { "name": "@corbado/web-core", - "version": "3.7.0-alpha.2", + "version": "3.7.0-alpha.3", "description": "This package contains core functionalities which are exported by all the SDKs and UI packages of our JavaScript library", "author": "Abdullah Shahbaz ", "homepage": "https://github.com/corbado/javascript#readme",