diff --git a/.eslintrc-ts.js b/.eslintrc-ts.js index aacb721..db8ab95 100644 --- a/.eslintrc-ts.js +++ b/.eslintrc-ts.js @@ -38,5 +38,7 @@ module.exports = { '@typescript-eslint/prefer-string-starts-ends-with': 'off', 'no-shadow': 'off', + + 'no-console': ['warn', { allow: ['warn', 'error'] }], }, }; diff --git a/README.md b/README.md index 9219687..6d313f9 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,10 @@ --- +ℹ️ Версия VK ID SDK 2.0.0-alpha поддерживает авторизацию по протоколу [OAuth 2.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-10), а также способы входа через аккаунты Одноклассников и Mail.ru. Если вы хотите участвовать в тестировании этой версии SDK или узнать о ней подробнее, напишите нам на почту devsupport@corp.vk.com. + +--- + VK ID SDK сейчас находится в бета-тестировании. О проблемах вы можете сообщить с помощью issues репозитория. --- @@ -53,7 +57,7 @@ pnpm add @vkid/sdk **CDN:** ```html - + ``` > Обратите внимание: Для работы авторизации нужен APP_ID. Вы получите его, когда [создадите](https://id.vk.com/business/go/docs/ru/vkid/latest/vk-id/connection/create-application) приложение в кабинете подключения VK ID. @@ -66,15 +70,20 @@ pnpm add @vkid/sdk ```javascript import * as VKID from '@vkid/sdk'; -VKID.Config.set({ +VKID.Config.init({ app: APP_ID, - redirectUrl: 'https://example.com' + redirectUrl: 'https://example.com', + state: 'state', + codeVerifier: 'codeVerifier', + scope: 'phone email', }); const authButton = document.createElement('button'); authButton.onclick = () => { - VKID.Auth.login(); // После авторизации будет редирект на адрес, указанный в параметре redirect_uri + // После авторизации будет редирект на адрес, указанный в параметре redirectUrl + VKID.Auth.login() + .catch(console.error); }; document.getElementById('container').appendChild(authButton); @@ -87,9 +96,12 @@ document.getElementById('container').appendChild(authButton); ```javascript import * as VKID from '@vkid/sdk'; -VKID.Config.set({ +VKID.Config.init({ app: APP_ID, - redirectUrl: 'https://example.com' + redirectUrl: 'https://example.com', + state: 'state', + codeVerifier: 'codeVerifier', + scope: 'phone email', }); const oneTap = new VKID.OneTap(); @@ -97,16 +109,18 @@ const oneTap = new VKID.OneTap(); const container = document.getElementById('VkIdSdkOneTap'); if (container) { - oneTap.render({ container }); + oneTap + .render({ container }) + .on(VKID.WidgetEvents.ERROR, console.error); } ``` ## Документация -- [Что такое VK ID](https://id.vk.com/business/go/docs/ru/vkid/latest/vk-id/intro/start-page) -- [Создание приложения](https://id.vk.com/business/go/docs/ru/vkid/latest/vk-id/connection/create-application) -- [Требования к дизайну](https://id.vk.com/business/go/docs/ru/vkid/archive/1.60/vk-id/guidelines/design-rules) +- [Что такое VK ID](https://id.vk.com/about/business/go/docs/ru/vkid/latest/vk-id-2/intro/start-page) +- [Создание приложения](https://id.vk.com/about/business/go/docs/ru/vkid/latest/vk-id-2/connection/create-application) +- [Требования к дизайну](https://id.vk.com/about/business/go/docs/ru/vkid/latest/vk-id-2/connection/guidelines/design-rules-oauth) - [Спецификация](https://vkcom.github.io/vkid-web-sdk/) ## Contributing diff --git a/__tests__/auth/auth.tests.ts b/__tests__/auth/auth.tests.ts index ff43b57..80c865c 100644 --- a/__tests__/auth/auth.tests.ts +++ b/__tests__/auth/auth.tests.ts @@ -1,7 +1,10 @@ -import { AUTH_RESPONSE_TOKEN, AUTH_VK_CONNECT_RESPONSE } from '#/auth/constants'; -import { Auth, AuthParams, AuthResponse, Config, ConfigAuthMode, Languages, Scheme } from '#/index'; +import { OAUTH2_RESPONSE, OAUTH2_RESPONSE_TYPE } from '#/auth/constants'; +import { AuthStatsFlowSource } from '#/auth/types'; +import { Auth, AuthParams, AuthResponse, Config, ConfigAuthMode, Languages, Prompt, Scheme } from '#/index'; +import { codeVerifier as codeVerifierCookie, state as stateCookie } from '#/utils/cookie'; import { version } from '../../package.json'; +import { WINDOW_LOCATION_HOST } from '../constants'; const APP_ID = 100; @@ -9,6 +12,7 @@ const openFn = jest.fn(); const closeFn = jest.fn(); const assignFn = jest.fn(); const eventListenerFn = jest.fn(); +const fetchFn = jest.fn(); describe('Auth', () => { beforeAll(() => { @@ -20,134 +24,148 @@ describe('Auth', () => { includes: jest.fn(), }, assign: assignFn, + host: WINDOW_LOCATION_HOST, }, writable: true, }); window.addEventListener = eventListenerFn; + window.fetch = fetchFn; }); beforeEach(() => { - Config.set({ app: APP_ID, redirectUrl: 'https://id.vk.com', state: 'test' }); + Config.init({ app: APP_ID, redirectUrl: 'https://id.vk.com', state: 'state', codeVerifier: 'codeVerifier', mode: ConfigAuthMode.Redirect }); reporter .addLabel('layer', 'unit') .feature('Units') .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'Auth') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); - test('Should redirect to url with default fields', () => { - Auth.login(); + test('Should redirect to url with default fields', async () => { + await Auth.login(); expect(assignFn).toHaveBeenCalled(); const callArgs: string[] = assignFn.mock.calls[0]; - const location = new URL(callArgs[0]).search.split(/[?&]/); + const searchParams = new URLSearchParams(new URL(callArgs[0]).search); const expectArr = [ - expect(location[0]).toEqual(''), - expect(location[1]).toContain('uuid'), - expect(location[2]).toEqual(`response_type=${AUTH_RESPONSE_TOKEN}`), - expect(location[3]).toEqual(`v=%22${version}%22`), - expect(location[4]).toEqual('sdk_type=vkid'), - expect(location[5]).toEqual(`app_id=${APP_ID}`), - expect(location[6]).toEqual('redirect_uri=https%3A%2F%2Fid.vk.com'), - expect(location[7]).toEqual('redirect_state=test'), + expect(searchParams.get('code_challenge')).toEqual('stringified_SHA256-STRING'), + expect(searchParams.get('code_challenge_method')).toEqual('s256'), + expect(searchParams.get('client_id')).toEqual(Config.get().app.toString()), + expect(searchParams.get('response_type')).toEqual(OAUTH2_RESPONSE_TYPE), + expect(searchParams.get('state')).toEqual(Config.get().state), + expect(searchParams.get('v')).toEqual(`\"${version}\"`), + expect(searchParams.get('sdk_type')).toEqual('vkid'), + expect(searchParams.get('app_id')).toEqual(APP_ID.toString()), + expect(searchParams.get('redirect_uri')).toEqual(Config.get().redirectUrl), + expect(searchParams.get('prompt')).toEqual(''), ]; - expect(location.length).toEqual(expectArr.length); + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); }); - test('Should redirect to url with additional fields', () => { + test('Should redirect to url with additional fields', async () => { const params: AuthParams = { scheme: Scheme.LIGHT, lang: Languages.RUS, screen: 'phone', + statsFlowSource: AuthStatsFlowSource.BUTTON_ONE_TAP, }; - Auth.login(params); + await Auth.login(params); expect(assignFn).toHaveBeenCalled(); const callArgs: string[] = assignFn.mock.calls[0]; - const location = new URL(callArgs[0]).search.split(/[?&]/); + const searchParams = new URLSearchParams(new URL(callArgs[0]).search); const expectArr = [ - expect(location[0]).toEqual(''), - expect(location[1]).toContain('uuid'), - expect(location[2]).toEqual(`lang_id=${params.lang}`), - expect(location[3]).toEqual(`scheme=${params.scheme}`), - expect(location[4]).toEqual('screen=phone'), - expect(location[5]).toEqual(`response_type=${AUTH_RESPONSE_TOKEN}`), - expect(location[6]).toEqual(`v=%22${version}%22`), - expect(location[7]).toEqual('sdk_type=vkid'), - expect(location[8]).toEqual(`app_id=${APP_ID}`), - expect(location[9]).toEqual('redirect_uri=https%3A%2F%2Fid.vk.com'), - expect(location[10]).toEqual('redirect_state=test'), + expect(searchParams.get('lang_id')).toEqual(params.lang?.toString()), + expect(searchParams.get('scheme')).toEqual(params.scheme), + expect(searchParams.get('code_challenge')).toEqual('stringified_SHA256-STRING'), + expect(searchParams.get('code_challenge_method')).toEqual('s256'), + expect(searchParams.get('client_id')).toEqual(Config.get().app.toString()), + expect(searchParams.get('response_type')).toEqual(OAUTH2_RESPONSE_TYPE), + expect(searchParams.get('state')).toEqual(Config.get().state), + expect(searchParams.get('redirect_state')).toEqual(Config.get().state), + expect(searchParams.get('v')).toEqual(`\"${version}\"`), + expect(searchParams.get('sdk_type')).toEqual('vkid'), + expect(searchParams.get('app_id')).toEqual(APP_ID.toString()), + expect(searchParams.get('redirect_uri')).toEqual(Config.get().redirectUrl), + expect(searchParams.get('prompt')).toEqual(''), + expect(searchParams.get('stats_flow_source')).toEqual(AuthStatsFlowSource.BUTTON_ONE_TAP), + expect(searchParams.get('screen')).toEqual(params.screen), + expect(searchParams.get('oauth_version')).toEqual('2'), ]; - expect(location.length).toEqual(expectArr.length); + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); }); test('Opens a window with default fields', () => { - Config.set({ mode: ConfigAuthMode.InNewTab }); - Auth.login(); + Config.update({ mode: ConfigAuthMode.InNewTab }); + Auth.login().catch(console.error); expect(openFn).toHaveBeenCalled(); const callArgs: string[] = openFn.mock.calls[0]; - const location = new URL(callArgs[0]).search.split(/[?&]/); + const searchParams = new URLSearchParams(new URL(callArgs[0]).search); const expectArr = [ - expect(location[0]).toEqual(''), - expect(location[1]).toContain('uuid'), - expect(location[2]).toEqual(`response_type=${AUTH_RESPONSE_TOKEN}`), - expect(location[3]).toContain('origin'), - expect(location[4]).toEqual(`v=%22${version}%22`), - expect(location[5]).toEqual('sdk_type=vkid'), - expect(location[6]).toEqual(`app_id=${APP_ID}`), - expect(location[7]).toEqual('redirect_uri=https%3A%2F%2Fid.vk.com'), - expect(location[8]).toEqual('redirect_state=test'), + expect(searchParams.get('code_challenge')).toEqual('stringified_SHA256-STRING'), + expect(searchParams.get('code_challenge_method')).toEqual('s256'), + expect(searchParams.get('client_id')).toEqual(Config.get().app.toString()), + expect(searchParams.get('response_type')).toEqual(OAUTH2_RESPONSE_TYPE), + expect(searchParams.get('state')).toEqual(Config.get().state), + expect(searchParams.get('v')).toEqual(`\"${version}\"`), + expect(searchParams.get('sdk_type')).toEqual('vkid'), + expect(searchParams.get('app_id')).toEqual(APP_ID.toString()), + expect(searchParams.get('redirect_uri')).toEqual(Config.get().redirectUrl), + expect(searchParams.get('prompt')).toEqual(''), ]; - expect(location.length).toEqual(expectArr.length); + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); }); test('Opens a window with additional fields', () => { - Config.set({ mode: ConfigAuthMode.InNewTab }); + Config.update({ mode: ConfigAuthMode.InNewTab, prompt: [Prompt.Login, Prompt.Consent] }); const params: AuthParams = { scheme: Scheme.LIGHT, lang: Languages.RUS, }; - Auth.login(params); + Auth.login(params).catch(console.error); expect(openFn).toHaveBeenCalled(); const callArgs: string[] = openFn.mock.calls[0]; - const location = new URL(callArgs[0]).search.split(/[?&]/); + const searchParams = new URLSearchParams(new URL(callArgs[0]).search); const expectArr = [ - expect(location[0]).toEqual(''), - expect(location[1]).toContain('uuid'), - expect(location[2]).toEqual(`lang_id=${params.lang}`), - expect(location[3]).toEqual(`scheme=${params.scheme}`), - expect(location[4]).toEqual(`response_type=${AUTH_RESPONSE_TOKEN}`), - expect(location[5]).toContain('origin'), - expect(location[6]).toEqual(`v=%22${version}%22`), - expect(location[7]).toEqual('sdk_type=vkid'), - expect(location[8]).toEqual(`app_id=${APP_ID}`), - expect(location[9]).toEqual('redirect_uri=https%3A%2F%2Fid.vk.com'), - expect(location[10]).toEqual('redirect_state=test'), + expect(searchParams.get('lang_id')).toEqual(params.lang?.toString()), + expect(searchParams.get('scheme')).toEqual(params.scheme), + expect(searchParams.get('code_challenge')).toEqual('stringified_SHA256-STRING'), + expect(searchParams.get('code_challenge_method')).toEqual('s256'), + expect(searchParams.get('client_id')).toEqual(Config.get().app.toString()), + expect(searchParams.get('response_type')).toEqual(OAUTH2_RESPONSE_TYPE), + expect(searchParams.get('state')).toEqual(Config.get().state), + expect(searchParams.get('v')).toEqual(`\"${version}\"`), + expect(searchParams.get('sdk_type')).toEqual('vkid'), + expect(searchParams.get('app_id')).toEqual(APP_ID.toString()), + expect(searchParams.get('redirect_uri')).toEqual(Config.get().redirectUrl), + expect(searchParams.get('prompt')).toEqual([Prompt.Login, Prompt.Consent].join(' ').trim()), ]; - expect(location.length).toEqual(expectArr.length); + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); }); test('Must redirect with payload', async () => { - Config.set({ mode: ConfigAuthMode.InNewTab }); + Config.update({ mode: ConfigAuthMode.InNewTab }); const response: AuthResponse = { - token: 'token', - type: 'silent_token', - ttl: 500, + code: 'code', + type: 'code_v2', + state: 'state', + device_id: 'device_id', }; const opener = { closed: false, @@ -156,10 +174,10 @@ describe('Auth', () => { openFn.mockReturnValue(opener); eventListenerFn.mockImplementation((event, callback) => { callback({ - origin: 'vk.com', + origin: 'id.vk.com', source: opener, data: { - action: AUTH_VK_CONNECT_RESPONSE + 'abc', + action: `${OAUTH2_RESPONSE}state`, payload: response, }, }); @@ -171,14 +189,135 @@ describe('Auth', () => { expect(assignFn).toHaveBeenCalled(); const callArgs: string[] = assignFn.mock.calls[0]; - const location = new URL(callArgs[0]).search.split(/[?&]/); + const searchParams = new URLSearchParams(new URL(callArgs[0]).search); + + const expectArr = [ + expect(searchParams.get('type')).toEqual('code_v2'), + expect(searchParams.get('code')).toEqual('code'), + expect(searchParams.get('state')).toEqual('state'), + expect(searchParams.get('device_id')).toEqual('device_id'), + ]; + + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); + }); + + test('Should fetch oauth2/auth with authorization_code exchange params', async () => { + await Auth.login(); + const { redirectUrl, app, codeVerifier, state } = Config.get(); + const mockResponse = { json() { + return Promise.resolve(JSON.parse('{ "state": "state" }')); + } }; + fetchFn.mockImplementation(() => Promise.resolve(mockResponse)); + + await Auth.exchangeCode('code', 'deviceId'); + + const searchParams = new URLSearchParams(new URL(fetchFn.mock.calls[0][0]).search); + const expectArr = [ + expect(searchParams.get('grant_type')).toEqual('authorization_code'), + expect(searchParams.get('redirect_uri')).toEqual(redirectUrl), + expect(searchParams.get('client_id')).toEqual(app.toString()), + expect(searchParams.get('code_verifier')).toEqual(codeVerifier), + expect(searchParams.get('state')).toEqual(state), + expect(searchParams.get('device_id')).toEqual('deviceId'), + ]; + + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); + expect(fetchFn).lastCalledWith(expect.any(String), { + body: new URLSearchParams({ code: 'code' }), + method: 'POST', + }); + }); + + test('Should set state and codeVerifier params to cookie after login()', async () => { + codeVerifierCookie('1'); + stateCookie('1'); + + await Auth.login(); + const { codeVerifier, state } = Config.get(); + + expect(codeVerifier).toEqual(codeVerifierCookie()); + expect(state).toEqual(stateCookie()); + }); + + test('Should clear state and codeVerifier params to cookie after exchangeCode()', async () => { + const mockResponse = { json() { + return Promise.resolve(JSON.parse('{ "state": "state", "access_token": "access_token", "refresh_token": "refresh_token" }')); + } }; + fetchFn.mockImplementation(() => Promise.resolve(mockResponse)); + + await Auth.exchangeCode('code', 'deviceId'); + expect(document.cookie).toBeFalsy(); + }); + + test('Should fetch oauth2/auth with refresh_token params', async () => { + const { redirectUrl, app, state } = Config.get(); + + await Auth.refreshToken('refreshToken', 'deviceId'); + const searchParams = new URLSearchParams(new URL(fetchFn.mock.calls[0][0]).search); const expectArr = [ - expect(location[0]).toEqual(''), - expect(location[1]).toEqual('payload=%7B%22type%22%3A%22silent_token%22%2C%22token%22%3A%22token%22%2C%22ttl%22%3A500%7D'), - expect(location[2]).toEqual('state=test'), + expect(searchParams.get('grant_type')).toEqual('refresh_token'), + expect(searchParams.get('redirect_uri')).toEqual(redirectUrl), + expect(searchParams.get('client_id')).toEqual(app.toString()), + expect(searchParams.get('state')).toEqual(state), + expect(searchParams.get('device_id')).toEqual('deviceId'), ]; - expect(location.length).toEqual(expectArr.length); + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); + expect(fetchFn).lastCalledWith(expect.any(String), { + body: new URLSearchParams({ refresh_token: 'refreshToken' }), + method: 'POST', + }); + }); + + test('Should fetch oauth2/logout with logout params', async () => { + const { app } = Config.get(); + + await Auth.logout('accessToken'); + + const searchParams = new URLSearchParams(new URL(fetchFn.mock.calls[0][0]).search); + const expectArr = [ + expect(searchParams.get('client_id')).toEqual(app.toString()), + ]; + + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); + expect(fetchFn).lastCalledWith(expect.any(String), { + body: new URLSearchParams({ access_token: 'accessToken' }), + method: 'POST', + }); + }); + + test('Should fetch oauth2/user_info with user_info params', async () => { + const { app } = Config.get(); + + await Auth.userInfo('accessToken'); + + const searchParams = new URLSearchParams(new URL(fetchFn.mock.calls[0][0]).search); + const expectArr = [ + expect(searchParams.get('client_id')).toEqual(app.toString()), + ]; + + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); + expect(fetchFn).lastCalledWith(expect.any(String), { + body: new URLSearchParams({ access_token: 'accessToken' }), + method: 'POST', + }); + }); + + test('Should fetch oauth2/public_info with public_info params', async () => { + const { app } = Config.get(); + + await Auth.publicInfo('idToken'); + + const searchParams = new URLSearchParams(new URL(fetchFn.mock.calls[0][0]).search); + const expectArr = [ + expect(searchParams.get('client_id')).toEqual(app.toString()), + ]; + + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); + expect(fetchFn).lastCalledWith(expect.any(String), { + body: new URLSearchParams({ id_token: 'idToken' }), + method: 'POST', + }); }); }); diff --git a/__tests__/auth/authDataService.tests.ts b/__tests__/auth/authDataService.tests.ts index e7e1650..7d74cc9 100644 --- a/__tests__/auth/authDataService.tests.ts +++ b/__tests__/auth/authDataService.tests.ts @@ -1,6 +1,7 @@ import { AuthDataService } from '#/auth/authDataService'; import { AUTH_ERROR_TEXT } from '#/auth/constants'; -import { AuthErrorCode } from '#/auth/types'; +import { AuthErrorCode, AuthResponse } from '#/auth/types'; +import { state } from '#/utils/cookie'; describe('AuthDataService', () => { beforeEach(() => { @@ -10,24 +11,26 @@ describe('AuthDataService', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'AuthDataService') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); test('Must return data on successful completion', async () => { const dataService = new AuthDataService(); - const successData = { - additionally: 'additionally', - token: 'token', - type: 'type', - ttl: 600, + const successData: AuthResponse = { + code: 'code', + state: 'state', + type: 'code_v2', + device_id: 'device_id', }; dataService.sendSuccessData(successData); const data = await dataService.value; expect(data).toEqual({ - token: 'token', - type: 'type', - ttl: 600, + code: 'code', + type: 'code_v2', + state: 'state', + device_id: 'device_id', }); }); @@ -35,7 +38,8 @@ describe('AuthDataService', () => { const dataService = new AuthDataService(); const error = { code: AuthErrorCode.NewTabHasBeenClosed, - text: AUTH_ERROR_TEXT[AuthErrorCode.NewTabHasBeenClosed], + error: AUTH_ERROR_TEXT[AuthErrorCode.NewTabHasBeenClosed], + state: state(), }; dataService.sendNewTabHasBeenClosed(); @@ -51,7 +55,8 @@ describe('AuthDataService', () => { const dataService = new AuthDataService(); const error = { code: AuthErrorCode.EventNotSupported, - text: AUTH_ERROR_TEXT[AuthErrorCode.EventNotSupported], + error: AUTH_ERROR_TEXT[AuthErrorCode.EventNotSupported], + state: state(), }; dataService.sendEventNotSupported(); @@ -67,7 +72,8 @@ describe('AuthDataService', () => { const dataService = new AuthDataService(); const error = { code: AuthErrorCode.CannotCreateNewTab, - text: AUTH_ERROR_TEXT[AuthErrorCode.CannotCreateNewTab], + error: AUTH_ERROR_TEXT[AuthErrorCode.CannotCreateNewTab], + state: state(), }; dataService.sendCannotCreateNewTab(); @@ -86,7 +92,9 @@ describe('AuthDataService', () => { }; const error = { code: AuthErrorCode.AuthorizationFailed, - text: AUTH_ERROR_TEXT[AuthErrorCode.AuthorizationFailed], + error: AUTH_ERROR_TEXT[AuthErrorCode.AuthorizationFailed], + state: state(), + error_description: additionally, }; dataService.sendAuthorizationFailed(additionally); @@ -94,7 +102,7 @@ describe('AuthDataService', () => { try { await dataService.value; } catch (e) { - expect(e).toEqual({ ...error, details: additionally }); + expect(e).toEqual({ ...error, error_description: JSON.stringify(additionally) }); } }); }); diff --git a/__tests__/core/analytics/ActionStatsCollector.tests.ts b/__tests__/core/analytics/ActionStatsCollector.tests.ts new file mode 100644 index 0000000..ebd9486 --- /dev/null +++ b/__tests__/core/analytics/ActionStatsCollector.tests.ts @@ -0,0 +1,52 @@ +import { ProductionStatsEventScreen } from '#/core/analytics'; +import { ActionStatsCollector } from '#/core/analytics/ActionStatsCollector'; +import { ProductionStatsCollector } from '#/core/analytics/ProductionStatsCollector'; +import { ProductionStatsEventTypes, ProductionStatsTypeActions } from '#/core/analytics/types'; +import { Config } from '#/core/config'; +import { request } from '#/utils/request'; + +import { wait } from '../../utils'; + +const requestMocked = jest.mocked(request); + +describe('ActionStatsCollector', () => { + beforeEach(() => { + reporter + .addLabel('layer', 'unit') + .feature('Units') + .addLabel('Platform', 'Web') + .addLabel('Product', 'VK ID SDK') + .addLabel('Component', 'ActionStatsCollector') + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); + }); + + it('Log event', async () => { + const config = new Config(); + const productStatsCollector = new ProductionStatsCollector(config); + const actionStatsCollector = new ActionStatsCollector(productStatsCollector); + + void actionStatsCollector.logEvent(ProductionStatsEventScreen.NOWHERE, { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: { + event_type: 'screen_proceed', + }, + }); + + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining({ + screen: ProductionStatsEventScreen.NOWHERE, + type: ProductionStatsEventTypes.TYPE_ACTION, + [ProductionStatsEventTypes.TYPE_ACTION]: { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: { + event_type: 'screen_proceed', + }, + }, + })); + }); +}); diff --git a/__tests__/core/analytics/ProductionStatsCollector.tests.ts b/__tests__/core/analytics/ProductionStatsCollector.tests.ts new file mode 100644 index 0000000..48646ec --- /dev/null +++ b/__tests__/core/analytics/ProductionStatsCollector.tests.ts @@ -0,0 +1,89 @@ +import { ProductionStatsEventScreen } from '#/core/analytics'; +import { ProductionStatsCollector } from '#/core/analytics/ProductionStatsCollector'; +import { ProductionStatsEvent, ProductionStatsEventTypes, ProductionStatsTypeActions } from '#/core/analytics/types'; +import { Config } from '#/core/config'; +import { request } from '#/utils/request'; + +import { wait } from '../../utils'; + +const requestMocked = jest.mocked(request); + +describe('ProductionStatsCollector', () => { + beforeEach(() => { + reporter + .addLabel('layer', 'unit') + .feature('Units') + .addLabel('Platform', 'Web') + .addLabel('Product', 'VK ID SDK') + .addLabel('Component', 'ProductionStatsCollector') + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); + }); + + it('Check base event', async () => { + const config = new Config(); + const productStatsCollector = new ProductionStatsCollector(config); + + expect(productStatsCollector.getBaseEvent(ProductionStatsEventScreen.NOWHERE)).toMatchObject(expect.objectContaining({ + prev_event_id: 0, + prev_nav_id: 0, + url: window.location.href, + screen: ProductionStatsEventScreen.NOWHERE, + })); + }); + + it('Log event', async () => { + const config = new Config(); + const productStatsCollector = new ProductionStatsCollector(config); + const event: ProductionStatsEvent = { + id: 10, + timestamp: '0000', + url: 'url', + screen: ProductionStatsEventScreen.NOWHERE, + type: ProductionStatsEventTypes.TYPE_ACTION, + [ProductionStatsEventTypes.TYPE_ACTION]: { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: { + event_type: 'screen_proceed', + }, + }, + }; + + void productStatsCollector.logEvent(event); + + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toEqual(event); + }); + + it('Log batching event', async () => { + const config = new Config(); + const productStatsCollector = new ProductionStatsCollector(config); + const event: ProductionStatsEvent = { + id: 10, + timestamp: '0000', + url: 'url', + screen: ProductionStatsEventScreen.NOWHERE, + type: ProductionStatsEventTypes.TYPE_ACTION, + [ProductionStatsEventTypes.TYPE_ACTION]: { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: { + event_type: 'screen_proceed', + }, + }, + }; + + void productStatsCollector.logEvent(event); + void productStatsCollector.logEvent(event); + + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events); + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toEqual([event, event]); + }); +}); diff --git a/__tests__/core/analytics/RegistrationStatsCollector.tests.ts b/__tests__/core/analytics/RegistrationStatsCollector.tests.ts new file mode 100644 index 0000000..1374546 --- /dev/null +++ b/__tests__/core/analytics/RegistrationStatsCollector.tests.ts @@ -0,0 +1,46 @@ +import { ProductionStatsEventScreen, RegistrationStatsCollector } from '#/core/analytics'; +import { ProductionStatsEventTypes, ProductionStatsTypeActions } from '#/core/analytics/types'; +import { Config } from '#/core/config'; +import { request } from '#/utils/request'; + +import { wait } from '../../utils'; + +const requestMocked = jest.mocked(request); + +describe('RegistrationStatsCollector', () => { + beforeEach(() => { + reporter + .addLabel('layer', 'unit') + .feature('Units') + .addLabel('Platform', 'Web') + .addLabel('Product', 'VK ID SDK') + .addLabel('Component', 'RegistrationStatsCollector') + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); + }); + + it('Log event', async () => { + const config = new Config(); + const registrationStatsCollector = new RegistrationStatsCollector(config); + + void registrationStatsCollector.logEvent(ProductionStatsEventScreen.NOWHERE, { + event_type: 'screen_proceed', + }); + + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining({ + screen: ProductionStatsEventScreen.NOWHERE, + type: ProductionStatsEventTypes.TYPE_ACTION, + [ProductionStatsEventTypes.TYPE_ACTION]: { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: { + event_type: 'screen_proceed', + }, + }, + })); + }); +}); diff --git a/__tests__/core/config/config.tests.ts b/__tests__/core/config/config.tests.ts index 151875a..82e8fb4 100644 --- a/__tests__/core/config/config.tests.ts +++ b/__tests__/core/config/config.tests.ts @@ -8,7 +8,8 @@ describe('Config', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'Config') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); it('Should get default properties', () => { const config = new Config(); @@ -25,8 +26,9 @@ describe('Config', () => { const config = new Config(); const OVERRIDE_STRING = 'Ryoji'; - config.set({ + config.init({ app: 100, + codeVerifier: OVERRIDE_STRING, state: OVERRIDE_STRING, redirectUrl: OVERRIDE_STRING, __loginDomain: OVERRIDE_STRING, @@ -37,6 +39,7 @@ describe('Config', () => { expect(config.get()).toBeTruthy(); expect(config.get().app).toBe(100); expect(config.get().state).toBe(OVERRIDE_STRING); + expect(config.get().codeVerifier).toBe(OVERRIDE_STRING); expect(config.get().redirectUrl).toBe(OVERRIDE_STRING); expect(config.get().__loginDomain).toBe(OVERRIDE_STRING); expect(config.get().__oauthDomain).toBe(OVERRIDE_STRING); diff --git a/__tests__/core/cookie/cookie.tests.ts b/__tests__/core/cookie/cookie.tests.ts new file mode 100644 index 0000000..646bdff --- /dev/null +++ b/__tests__/core/cookie/cookie.tests.ts @@ -0,0 +1,44 @@ +import { Config } from '#/index'; +import { clearCodeVerifierCookie, clearStateCookie, codeVerifier, state } from '#/utils/cookie'; + +const APP_ID = 100; + +describe('Cookie', () => { + beforeEach(() => { + Config.init({ app: APP_ID, redirectUrl: 'test' }); + + reporter + .addLabel('layer', 'unit') + .feature('Units') + .addLabel('Platform', 'Web') + .addLabel('Product', 'VK ID SDK') + .addLabel('Component', 'Cookie') + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); + }); + + it('Should set default state and codeVerifier cookies', () => { + expect(state()).toBe('nanoid'); + expect(codeVerifier()).toBe('nanoid'); + }); + + it('Should set custom state and codeVerifier cookies', () => { + const CUSTOM_TEXT = 'custom text'; + + state(CUSTOM_TEXT); + codeVerifier(CUSTOM_TEXT); + + expect(state()).toBe(CUSTOM_TEXT); + expect(codeVerifier()).toBe(CUSTOM_TEXT); + }); + + it('Should clear state and codeVerifier cookies', () => { + expect(state()).toBeTruthy(); + expect(codeVerifier()).toBeTruthy(); + + clearStateCookie(); + clearCodeVerifierCookie(); + + expect(document.cookie).toBeFalsy(); + }); +}); diff --git a/__tests__/core/dataService/dataService.tests.ts b/__tests__/core/dataService/dataService.tests.ts index 192cf08..b4f3c1e 100644 --- a/__tests__/core/dataService/dataService.tests.ts +++ b/__tests__/core/dataService/dataService.tests.ts @@ -8,7 +8,8 @@ describe('DataService', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'DataService') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); test('Must return data on successful completion', async () => { const dataService = new DataService(); diff --git a/__tests__/core/dispatcher/dispatcher.tests.ts b/__tests__/core/dispatcher/dispatcher.tests.ts index 93dfe92..6eae988 100644 --- a/__tests__/core/dispatcher/dispatcher.tests.ts +++ b/__tests__/core/dispatcher/dispatcher.tests.ts @@ -17,7 +17,8 @@ describe('Dispatcher', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'Dispatcher') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); it('should register event handler with on() method', () => { diff --git a/__tests__/core/validator/validationRule.tests.ts b/__tests__/core/validator/validationRule.tests.ts index 27d59af..2761398 100644 --- a/__tests__/core/validator/validationRule.tests.ts +++ b/__tests__/core/validator/validationRule.tests.ts @@ -8,7 +8,8 @@ describe('isNumber rule', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'isNumber rule') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); it('should return true', () => { expect(isNumber(1).result).toBeTruthy(); @@ -36,7 +37,8 @@ describe('isRequired rule', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'isRequired') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); it('should return true', () => { expect(isRequired(1).result).toBeTruthy(); @@ -62,7 +64,8 @@ describe('isValidAppId rule', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'isValidAppId rule') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); it('should return true', () => { expect(isValidAppId(undefined).result).toBeTruthy(); @@ -87,7 +90,8 @@ describe('isValidHeight rule', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'isValidHeight rule') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); it('should return true', () => { expect(isValidHeight(undefined).result).toBeTruthy(); diff --git a/__tests__/core/validator/validator.tests.ts b/__tests__/core/validator/validator.tests.ts index c854160..989e953 100644 --- a/__tests__/core/validator/validator.tests.ts +++ b/__tests__/core/validator/validator.tests.ts @@ -10,7 +10,8 @@ describe('Validator', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'Validator') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); it('one parameter, one rule', () => { const correctParams = { value1: 'Langley' }; diff --git a/__tests__/core/widget/widget.tests.ts b/__tests__/core/widget/widget.tests.ts index 20fbe6b..774b244 100644 --- a/__tests__/core/widget/widget.tests.ts +++ b/__tests__/core/widget/widget.tests.ts @@ -3,6 +3,7 @@ import { BridgeMessage } from '#/core/bridge'; import { BRIDGE_MESSAGE_TYPE_SDK } from '#/core/bridge/bridge'; import { Widget, WidgetEvents } from '#/core/widget'; import { Config } from '#/index'; +import { codeVerifier as codeVerifierCookie, state as stateCookie } from '#/utils/cookie'; const APP_ID = 100; @@ -19,9 +20,9 @@ class TestWidget extends Widget { let widget: TestWidget; -describe('Data Policy', () => { +describe('Widget', () => { beforeEach(() => { - Config.set({ app: APP_ID }); + Config.init({ app: APP_ID, redirectUrl: 'test', state: 'state', codeVerifier: 'codeVerifier' }); widget = new TestWidget(); container = document.createElement('div', {}); @@ -35,8 +36,9 @@ describe('Data Policy', () => { .feature('Units') .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') - .addLabel('Component', 'Data Policy') - .addLabel('Suite', 'Units'); + .addLabel('Component', 'Widget') + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); afterEach(() => { @@ -55,7 +57,6 @@ describe('Data Policy', () => { expect(urlParams.get('origin')).toContain(location.protocol + '//' + location.host); expect(urlParams.get('code_challenge_method')).toContain('s256'); expect(frameSrc).toContain('id.vk.'); - expect(frameSrc).toContain('uuid'); }); test('Should remove root after close()', () => { @@ -115,4 +116,17 @@ describe('Data Policy', () => { expect(onHandlerFn).toBeCalledWith({ code: 1, text: 'internal error', details: { msg: 1 } }); }); + + test('Should set state and codeVerifier params to cookie after widget load', async () => { + const { codeVerifier, state } = Config.get(); + + codeVerifierCookie('1'); + stateCookie('1'); + + widget = new TestWidget(); + widget.render({ container }); + + expect(codeVerifier).toEqual(codeVerifierCookie()); + expect(state).toEqual(stateCookie()); + }); }); diff --git a/__tests__/jest-global-mock.js b/__tests__/jest-global-mock.js index 090ef86..f9988d6 100644 --- a/__tests__/jest-global-mock.js +++ b/__tests__/jest-global-mock.js @@ -15,7 +15,7 @@ jest.mock('crypto-js/enc-base64', () => ({ })); jest.mock('nanoid/non-secure', () => ({ - nanoid: () => 'verifier', + nanoid: () => 'nanoid', customAlphabet: (data, length) => () => `abc` })); @@ -30,3 +30,16 @@ window.env = { VERSION: JSON.stringify(version), DOMAIN: JSON.stringify('vk.com'), }; + +/** + * Mock fetch + */ + +global.fetch = jest.fn(() => Promise.resolve({ + json: () => Promise.resolve(), +})); + +jest.mock('#/utils/request', () => ({ + request: jest.fn().mockReturnValue(Promise.resolve()), + getStatsUrl: (value) => value, +})); diff --git a/__tests__/tsconfig.json b/__tests__/tsconfig.json index 5197ce2..d24101f 100644 --- a/__tests__/tsconfig.json +++ b/__tests__/tsconfig.json @@ -1,4 +1,9 @@ { "extends": "../tsconfig.json", - "include": ["./**/*.ts"] + "include": [ + "./**/*.ts" + ], + "compilerOptions": { + "target": "es2015" + } } diff --git a/__tests__/widgets/agreementsDialog/agreementsDialog.tests.ts b/__tests__/widgets/agreementsDialog/agreementsDialog.tests.ts index c47b622..46d0577 100644 --- a/__tests__/widgets/agreementsDialog/agreementsDialog.tests.ts +++ b/__tests__/widgets/agreementsDialog/agreementsDialog.tests.ts @@ -9,6 +9,7 @@ import { } from '#/widgets/agreementsDialog/events'; import { version } from '../../../package.json'; +import { WINDOW_LOCATION_URL } from '../../constants'; class TestAgreementsDialog extends AgreementsDialog { public onBridgeMessageHandler(event: BridgeMessage) { @@ -23,7 +24,7 @@ let agreementsDialog: TestAgreementsDialog; describe('Agreements Dialog', () => { beforeEach(() => { - Config.set({ app: APP_ID, redirectUrl: 'test' }); + Config.init({ app: APP_ID, redirectUrl: 'test', state: 'state', codeVerifier: 'codeVerifier' }); agreementsDialog = new TestAgreementsDialog(); agreementsDialog.render({ container: document.body }); @@ -35,7 +36,8 @@ describe('Agreements Dialog', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'Agreements Dialog') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); afterEach(() => { @@ -46,21 +48,24 @@ describe('Agreements Dialog', () => { expect(iframeElement).toBeTruthy(); const frameSrc = iframeElement.getAttribute('src') as string; - const location = frameSrc.split(/[?&]/); + const location = new URL(frameSrc); + const searchParams = new URLSearchParams(location.search); + + expect(location.href.split('?')[0]).toEqual('https://id.vk.com/user_policy_agreements'); const expectArr = [ - expect(location[0]).toEqual('https://id.vk.com/user_policy_agreements'), - expect(location[1]).toContain('code_challenge=stringified_SHA256-STRING'), - expect(location[2]).toContain('code_challenge_method=s256'), - expect(location[3]).toContain('origin=https%3A%2F%2Frnd-service.ru'), - expect(frameSrc).toContain('uuid'), - expect(location[5]).toContain(`v=%22${version}%22`), - expect(location[6]).toContain('sdk_type=vkid'), - expect(location[7]).toContain('app_id=100'), - expect(location[8]).toContain('redirect_uri=test'), + expect(searchParams.get('origin')).toEqual(WINDOW_LOCATION_URL), + expect(searchParams.get('code_challenge')).toEqual('stringified_SHA256-STRING'), + expect(searchParams.get('code_challenge_method')).toEqual('s256'), + expect(searchParams.get('v')).toEqual(`\"${version}\"`), + expect(searchParams.get('sdk_type')).toEqual('vkid'), + expect(searchParams.get('app_id')).toEqual(APP_ID.toString()), + expect(searchParams.get('redirect_uri')).toEqual(Config.get().redirectUrl), + expect(searchParams.get('oauth_version')).toEqual('2'), + expect(searchParams.get('state')).toEqual(Config.get().state), ]; - expect(location.length).toEqual(expectArr.length); + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); }); test('Must close the iframe on the decline event', () => { diff --git a/__tests__/widgets/floatingOneTap/analytics/FloatingOneTapStatsCollector.tests.ts b/__tests__/widgets/floatingOneTap/analytics/FloatingOneTapStatsCollector.tests.ts new file mode 100644 index 0000000..cd8931a --- /dev/null +++ b/__tests__/widgets/floatingOneTap/analytics/FloatingOneTapStatsCollector.tests.ts @@ -0,0 +1,141 @@ +import { ProductionStatsEventScreen } from '#/core/analytics'; +import { ProductionStatsEventTypes, ProductionStatsTypeActions, RegistrationStatsEventParams } from '#/core/analytics/types'; +import { Config } from '#/core/config'; +import { Languages, Scheme } from '#/types'; +import { request } from '#/utils/request'; +import { FloatingOneTapContentId } from '#/widgets/floatingOneTap'; +import { FloatingOneTapStatsCollector } from '#/widgets/floatingOneTap/analytics'; +import { TEXT_TYPE } from '#/widgets/floatingOneTap/analytics/constants'; + +import { wait } from '../../../utils'; + +const requestMocked = jest.mocked(request); + +let statsCollector: FloatingOneTapStatsCollector; + +const getEvent = (event: RegistrationStatsEventParams) => ({ + screen: ProductionStatsEventScreen.FLOATING_ONE_TAP, + type: ProductionStatsEventTypes.TYPE_ACTION, + [ProductionStatsEventTypes.TYPE_ACTION]: { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: event, + }, +}); + +describe('FloatingOneTapStatsCollector', () => { + beforeAll(() => { + const config = new Config(); + statsCollector = new FloatingOneTapStatsCollector(config); + }); + + beforeEach(() => { + reporter + .addLabel('layer', 'unit') + .feature('Units') + .addLabel('Platform', 'Web') + .addLabel('Product', 'VK ID SDK') + .addLabel('Component', 'FloatingOneTapStatsCollector') + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); + }); + + it('Log ScreenProcessed', async () => { + void statsCollector.sendScreenProcessed({ + lang: Languages.RUS, + scheme: Scheme.DARK, + contentId: FloatingOneTapContentId.SIGN_IN_TO_ACCOUNT, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining({ + screen: ProductionStatsEventScreen.NOWHERE, + type: ProductionStatsEventTypes.TYPE_ACTION, + [ProductionStatsEventTypes.TYPE_ACTION]: { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: { + event_type: 'screen_proceed', + screen_to: ProductionStatsEventScreen.FLOATING_ONE_TAP, + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'theme_type', + value: Scheme.DARK, + }, { + name: 'language', + value: Languages.RUS.toString(), + }, { + name: 'text_type', + value: TEXT_TYPE[FloatingOneTapContentId.SIGN_IN_TO_ACCOUNT], + }], + }, + } })); + }); + + it('Log IframeLoadingFailed', async () => { + void statsCollector.sendIframeLoadingFailed(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'iframe_loading_failed', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }], + }))); + }); + + it('Log NoUserButtonShow', async () => { + void statsCollector.sendNoUserButtonShow(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'no_user_button_show', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }], + }))); + }); + + it('Log NoUserButtonTap', async () => { + void statsCollector.sendNoUserButtonTap(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'no_user_button_tap', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }], + }))); + }); + + it('Log SDK Init', async () => { + void statsCollector.sendSdkInit(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'sdk_init', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }], + }))); + }); +}); diff --git a/__tests__/widgets/floatingOneTap/floatingOneTap.tests.ts b/__tests__/widgets/floatingOneTap/floatingOneTap.tests.ts index 273972b..e9e5115 100644 --- a/__tests__/widgets/floatingOneTap/floatingOneTap.tests.ts +++ b/__tests__/widgets/floatingOneTap/floatingOneTap.tests.ts @@ -1,9 +1,11 @@ -import { BridgeMessage } from '#/core/bridge'; import { BRIDGE_MESSAGE_TYPE_SDK } from '#/core/bridge/bridge'; import { WidgetEvents } from '#/core/widget'; import { Config, FloatingOneTapContentId, Languages, OAuthName } from '#/index'; import { FloatingOneTap } from '#/widgets/floatingOneTap'; -import { FloatingOneTapInternalEvents } from '#/widgets/floatingOneTap/events'; +import { FloatingOneTapBridgeMessage } from '#/widgets/floatingOneTap/types'; + +import { WINDOW_LOCATION_URL } from '../../constants'; +import { wait } from '../../utils'; const APP_ID = 100; @@ -14,7 +16,7 @@ const openFn = jest.fn(); const removeEventListenerFn = jest.fn(); class TestFloatingOneTap extends FloatingOneTap { - public onBridgeMessageHandler(event: BridgeMessage) { + public onBridgeMessageHandler(event: FloatingOneTapBridgeMessage) { super.onBridgeMessageHandler(event); } } @@ -31,7 +33,7 @@ describe('FloatingOneTap', () => { }); beforeEach(() => { - Config.set({ app: APP_ID, redirectUrl: 'test', state: 'test' }); + Config.init({ app: APP_ID, redirectUrl: 'test', state: 'test', codeVerifier: 'codeVerifier' }); floatingOneTap = new TestFloatingOneTap(); reporter @@ -40,7 +42,8 @@ describe('FloatingOneTap', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'FloatingOneTap') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); afterEach(() => { @@ -57,27 +60,29 @@ describe('FloatingOneTap', () => { expect(iframeElement).toBeTruthy(); const frameSrc = iframeElement.getAttribute('src') as string; - const location = frameSrc.split(/[?&]/); + const location = new URL(frameSrc); + const searchParams = new URLSearchParams(location.search); + + expect(location.href.split('?')[0]).toEqual('https://id.vk.com/floating_one_tap_auth'); const expectArr = [ - expect(location[0]).toEqual('https://id.vk.com/floating_one_tap_auth'), - expect(location[1]).toEqual('scheme=light'), - expect(location[2]).toEqual('lang_id=0'), - expect(location[3]).toEqual('show_alternative_login=1'), - expect(location[4]).toEqual('content_id=0'), - expect(location[5]).toEqual('providers='), - expect(location[6]).toEqual('code_challenge=stringified_SHA256-STRING'), - expect(location[7]).toEqual('code_challenge_method=s256'), - expect(location[8]).toEqual('origin=https%3A%2F%2Frnd-service.ru'), - expect(frameSrc).toContain('uuid'), - expect(frameSrc).toContain('v'), - expect(location[11]).toEqual('sdk_type=vkid'), - expect(location[12]).toEqual('app_id=100'), - expect(location[13]).toEqual('redirect_uri=test'), - expect(location[14]).toEqual('redirect_state=test'), + expect(searchParams.get('scheme')).toEqual('light'), + expect(searchParams.get('lang_id')).toEqual('0'), + expect(searchParams.get('show_alternative_login')).toEqual('1'), + expect(searchParams.get('content_id')).toEqual('0'), + expect(searchParams.get('providers')).toEqual(''), + expect(searchParams.get('origin')).toEqual(WINDOW_LOCATION_URL), + expect(searchParams.get('code_challenge')).toEqual('stringified_SHA256-STRING'), + expect(searchParams.get('code_challenge_method')).toEqual('s256'), + expect(searchParams.get('v')).toBeTruthy(), + expect(searchParams.get('sdk_type')).toEqual('vkid'), + expect(searchParams.get('app_id')).toEqual('100'), + expect(searchParams.get('redirect_uri')).toEqual('test'), + expect(searchParams.get('oauth_version')).toEqual('2'), + expect(searchParams.get('state')).toEqual(Config.get().state), ]; - expect(location.length).toEqual(expectArr.length); + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); }); test('The lang_id parameter must be set', () => { @@ -120,7 +125,7 @@ describe('FloatingOneTap', () => { floatingOneTap.onBridgeMessageHandler({ type: BRIDGE_MESSAGE_TYPE_SDK, handler: WidgetEvents.ERROR, - params: { someData: 'token' }, + params: { uuid: 'token' }, }); const oneTapEl = document.querySelector('[data-test-id="floatingOneTap"]'); @@ -136,15 +141,11 @@ describe('FloatingOneTap', () => { floatingOneTap.onBridgeMessageHandler({ type: BRIDGE_MESSAGE_TYPE_SDK, handler: WidgetEvents.LOAD, - params: { someData: 'token' }, + params: { uuid: 'token' }, }); const oneTapEl = document.querySelector('[data-test-id="floatingOneTap"]'); - await new Promise((resolve) => { - setTimeout(() => { - resolve(''); - }, 400); - }); + await wait(400); expect(oneTapEl?.getAttribute('data-state')).toEqual('loaded'); }); @@ -153,12 +154,8 @@ describe('FloatingOneTap', () => { appName: 'VK ID Demo', oauthList: [OAuthName.MAIL, OAuthName.OK], }); - await new Promise((resolve) => { - setTimeout(() => { - resolve(''); - }, 0); - }); - const oneTapEl = document.querySelector('[data-test-id="floatingOneTap"]'); + await wait(0); + const oneTapEl = document.querySelector('[data-test-id="floatingOneTap"]') as HTMLElement; const oauthListEl = oneTapEl.querySelector('[data-test-id="oauthList"]'); expect(oauthListEl).toBeTruthy(); }); @@ -168,12 +165,8 @@ describe('FloatingOneTap', () => { appName: 'VK ID Demo', oauthList: [OAuthName.VK], }); - await new Promise((resolve) => { - setTimeout(() => { - resolve(''); - }, 0); - }); - const oneTapEl = document.querySelector('[data-test-id="floatingOneTap"]'); + await wait(0); + const oneTapEl = document.querySelector('[data-test-id="floatingOneTap"]') as HTMLElement; const oauthListEl = oneTapEl.querySelector('[data-test-id="oauthList"]'); expect(oauthListEl).toBeFalsy(); }); @@ -182,12 +175,8 @@ describe('FloatingOneTap', () => { floatingOneTap.render({ appName: 'VK ID Demo', }); - await new Promise((resolve) => { - setTimeout(() => { - resolve(''); - }, 0); - }); - const oneTapEl = document.querySelector('[data-test-id="floatingOneTap"]'); + await wait(0); + const oneTapEl = document.querySelector('[data-test-id="floatingOneTap"]') as HTMLElement; const oauthListEl = oneTapEl.querySelector('[data-test-id="oauthList"]'); expect(oauthListEl).toBeFalsy(); }); diff --git a/__tests__/widgets/oauthList/analytics/OAuthListStatsCollector.tests.ts b/__tests__/widgets/oauthList/analytics/OAuthListStatsCollector.tests.ts new file mode 100644 index 0000000..127d4df --- /dev/null +++ b/__tests__/widgets/oauthList/analytics/OAuthListStatsCollector.tests.ts @@ -0,0 +1,485 @@ +import { ProductionStatsEventScreen } from '#/core/analytics'; +import { ProductionStatsEventTypes, ProductionStatsTypeActions, RegistrationStatsEventParams } from '#/core/analytics/types'; +import { Config } from '#/core/config'; +import { request } from '#/utils/request'; +import { OAuthName } from '#/widgets/oauthList'; +import { MultibrandingStatsProviders, OAuthListStatsCollector } from '#/widgets/oauthList/analytics'; + +import { wait } from '../../../utils'; + +const requestMocked = jest.mocked(request); + +let statsCollector: OAuthListStatsCollector; + +const getEvent = (event: RegistrationStatsEventParams) => ({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + type: ProductionStatsEventTypes.TYPE_ACTION, + [ProductionStatsEventTypes.TYPE_ACTION]: { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: event, + }, +}); + +describe('OAuthListStatsCollector', () => { + beforeAll(() => { + const config = new Config(); + statsCollector = new OAuthListStatsCollector(config); + }); + + beforeEach(() => { + reporter + .addLabel('layer', 'unit') + .feature('Units') + .addLabel('Platform', 'Web') + .addLabel('Product', 'VK ID SDK') + .addLabel('Component', 'OAuthListStatsCollector') + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); + }); + + it('Log all selected providers', async () => { + const providers = new Set([ + OAuthName.VK, + OAuthName.OK, + OAuthName.MAIL, + ]); + + void statsCollector.sendMultibrandingOauthAdded({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + fields: [{ + name: MultibrandingStatsProviders.VK, + value: (+providers.has(OAuthName.VK)).toString(), + }, { + name: MultibrandingStatsProviders.OK, + value: (+providers.has(OAuthName.OK)).toString(), + }, { + name: MultibrandingStatsProviders.MAIL, + value: (+providers.has(OAuthName.MAIL)).toString(), + }], + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'multibranding_oauth_added', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'vk', + value: '1', + }, { + name: 'ok', + value: '1', + }, { + name: 'mail', + value: '1', + }], + }))); + }); + + it('Log the selected provider "OK"', async () => { + const providers = new Set([ + OAuthName.OK, + ]); + + void statsCollector.sendMultibrandingOauthAdded({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + fields: [{ + name: MultibrandingStatsProviders.VK, + value: (+providers.has(OAuthName.VK)).toString(), + }, { + name: MultibrandingStatsProviders.OK, + value: (+providers.has(OAuthName.OK)).toString(), + }, { + name: MultibrandingStatsProviders.MAIL, + value: (+providers.has(OAuthName.MAIL)).toString(), + }], + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'multibranding_oauth_added', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'vk', + value: '0', + }, { + name: 'ok', + value: '1', + }, { + name: 'mail', + value: '0', + }], + }))); + }); + + it('Log the selected provider "Mail"', async () => { + const providers = new Set([ + OAuthName.MAIL, + ]); + + void statsCollector.sendMultibrandingOauthAdded({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + fields: [{ + name: MultibrandingStatsProviders.VK, + value: (+providers.has(OAuthName.VK)).toString(), + }, { + name: MultibrandingStatsProviders.OK, + value: (+providers.has(OAuthName.OK)).toString(), + }, { + name: MultibrandingStatsProviders.MAIL, + value: (+providers.has(OAuthName.MAIL)).toString(), + }], + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'multibranding_oauth_added', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'vk', + value: '0', + }, { + name: 'ok', + value: '0', + }, { + name: 'mail', + value: '1', + }], + }))); + }); + + it('Log the selected provider "VK"', async () => { + const providers = new Set([ + OAuthName.VK, + ]); + + void statsCollector.sendMultibrandingOauthAdded({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + fields: [{ + name: MultibrandingStatsProviders.VK, + value: (+providers.has(OAuthName.VK)).toString(), + }, { + name: MultibrandingStatsProviders.OK, + value: (+providers.has(OAuthName.OK)).toString(), + }, { + name: MultibrandingStatsProviders.MAIL, + value: (+providers.has(OAuthName.MAIL)).toString(), + }], + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'multibranding_oauth_added', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'vk', + value: '1', + }, { + name: 'ok', + value: '0', + }, { + name: 'mail', + value: '0', + }], + }))); + }); + + it('Log the display of the "OK" button', async () => { + void statsCollector.sendOkButtonShow({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: false, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'ok_button_show', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'default', + }], + }))); + }); + + it('Log the display of the "Mail" button', async () => { + void statsCollector.sendMailButtonShow({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: false, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'mail_button_show', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'default', + }], + }))); + }); + + it('Log the display of the "VK" button', async () => { + void statsCollector.sendVkButtonShow({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: false, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'vk_button_show', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'default', + }], + }))); + }); + + it('Log the display of the "OK" icon', async () => { + void statsCollector.sendOkButtonShow({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: true, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'ok_button_show', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'icon', + }], + }))); + }); + + it('Log the display of the "Mail" icon', async () => { + void statsCollector.sendMailButtonShow({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: true, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'mail_button_show', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'icon', + }], + }))); + }); + + it('Log the display of the "VK" icon', async () => { + void statsCollector.sendVkButtonShow({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: true, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'vk_button_show', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'icon', + }], + }))); + }); + + it('Log clicking on the "OK" button', async () => { + void statsCollector.sendOkButtonTap({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: false, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'ok_button_tap', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'default', + }], + }))); + }); + + it('Log clicking on the "Mail" button', async () => { + void statsCollector.sendMailButtonTap({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: false, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'mail_button_tap', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'default', + }], + }))); + }); + + it('Log clicking on the "VK" button', async () => { + void statsCollector.sendVkButtonTap({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: false, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'vk_button_tap', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'default', + }], + }))); + }); + + it('Log clicking on the "OK" icon', async () => { + void statsCollector.sendOkButtonTap({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: true, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'ok_button_tap', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'icon', + }], + }))); + }); + + it('Log clicking on the "Mail" icon', async () => { + void statsCollector.sendMailButtonTap({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: true, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'mail_button_tap', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'icon', + }], + }))); + }); + + it('Log clicking on the "VK" icon', async () => { + void statsCollector.sendVkButtonTap({ + screen: ProductionStatsEventScreen.MULTIBRANDING, + isIcon: true, + }); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'vk_button_tap', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'icon', + }], + }))); + }); + + it('Log SDK Init', async () => { + void statsCollector.sendSdkInit(ProductionStatsEventScreen.MULTIBRANDING); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'sdk_init', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }], + }))); + }); +}); diff --git a/__tests__/widgets/oauthList/oauthList.tests.ts b/__tests__/widgets/oauthList/oauthList.tests.ts index 8efdb73..5dafcf3 100644 --- a/__tests__/widgets/oauthList/oauthList.tests.ts +++ b/__tests__/widgets/oauthList/oauthList.tests.ts @@ -1,6 +1,8 @@ -import { Config, Languages, OAuthList, OAuthName } from '#/index'; +import { Config, ConfigAuthMode, Languages, OAuthList, OAuthName, Prompt } from '#/index'; import { singleButtonText } from '#/widgets/oauthList/lang'; +import { wait } from '../../utils'; + const APP_ID = 100; let container: HTMLElement; @@ -30,7 +32,7 @@ describe('OAuthList', () => { }); beforeEach(() => { - Config.set({ app: APP_ID }); + Config.init({ app: APP_ID, redirectUrl: 'redirectUrl', codeVerifier: 'codeVerifier', state: 'state', mode: ConfigAuthMode.Redirect }); oauthList = new OAuthList(); container = document.createElement('div', {}); @@ -42,7 +44,8 @@ describe('OAuthList', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'OAuthList') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); afterEach(() => { @@ -69,11 +72,15 @@ describe('OAuthList', () => { expect(oauthListDiv?.getAttribute('data-single-mode')).not.toBeNull(); }); - test('Should open auth with correct action', () => { - oauthList.render({ container, oauthList: [OAuthName.VK] }); - const vkidButton = container.querySelector('[data-oauth="vkid"]') as HTMLDivElement; + test('Should open authorize with correct params', async () => { + oauthList.render({ container, oauthList: [OAuthName.OK] }); + const vkidButton = container.querySelector('[data-oauth="ok_ru"]') as HTMLDivElement; vkidButton.click(); - const action = JSON.stringify({ name: 'sdk_oauth', params: { oauth: 'vkid' } }); - expect(assignFn).toBeCalledWith(expect.stringContaining(`action=${encodeURIComponent(btoa(action))}`)); + await wait(0); + const callArgs: string[] = assignFn.mock.calls[0]; + const searchParams = new URLSearchParams(new URL(callArgs[0]).search); + + expect(searchParams.get('provider')).toEqual('ok_ru'); + expect(searchParams.get('prompt')).toEqual(Prompt.Login); }); }); diff --git a/__tests__/widgets/oneTap/analytics/OneTapStatsCollector.tests.ts b/__tests__/widgets/oneTap/analytics/OneTapStatsCollector.tests.ts new file mode 100644 index 0000000..23791bc --- /dev/null +++ b/__tests__/widgets/oneTap/analytics/OneTapStatsCollector.tests.ts @@ -0,0 +1,124 @@ +import { ProductionStatsEventScreen } from '#/core/analytics'; +import { ProductionStatsEventTypes, ProductionStatsTypeActions, RegistrationStatsEventParams } from '#/core/analytics/types'; +import { Config } from '#/core/config'; +import { request } from '#/utils/request'; +import { OneTapStatsCollector } from '#/widgets/oneTap/analytics'; + +import { wait } from '../../../utils'; + +const requestMocked = jest.mocked(request); + +let statsCollector: OneTapStatsCollector; + +const getEvent = (event: RegistrationStatsEventParams) => ({ + screen: ProductionStatsEventScreen.NOWHERE, + type: ProductionStatsEventTypes.TYPE_ACTION, + [ProductionStatsEventTypes.TYPE_ACTION]: { + type: ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM, + [ProductionStatsTypeActions.TYPE_REGISTRATION_ITEM]: event, + }, +}); + +describe('OneTapStatsCollector', () => { + beforeAll(() => { + const config = new Config(); + statsCollector = new OneTapStatsCollector(config); + }); + + beforeEach(() => { + reporter + .addLabel('layer', 'unit') + .feature('Units') + .addLabel('Platform', 'Web') + .addLabel('Product', 'VK ID SDK') + .addLabel('Component', 'OneTapStatsCollector') + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); + }); + + it('Log FrameLoadingFailed', async () => { + void statsCollector.sendFrameLoadingFailed(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'iframe_loading_failed', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }], + }))); + }); + + it('Log NoSessionFound', async () => { + void statsCollector.sendNoSessionFound(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'no_session_found', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }], + }))); + }); + + it('Log OneTapButtonNoUserShow', async () => { + void statsCollector.sendOneTapButtonNoUserShow(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'onetap_button_no_user_show', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'default', + }], + }))); + }); + + it('Log OneTapButtonNoUserTap', async () => { + void statsCollector.sendOneTapButtonNoUserTap(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'onetap_button_no_user_tap', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }, { + name: 'button_type', + value: 'default', + }], + }))); + }); + + it('Log SDK Init', async () => { + void statsCollector.sendSdkInit(); + await wait(0); + + const events = JSON.parse((requestMocked.mock.lastCall?.[1] as any).events)[0]; + + expect(request).toBeCalledWith('stat_events_vkid_sdk', expect.any(Object)); + expect(events).toMatchObject(expect.objectContaining(getEvent({ + event_type: 'sdk_init', + fields: [{ + name: 'sdk_type', + value: 'vkid', + }], + }))); + }); +}); diff --git a/__tests__/widgets/oneTap/oneTap.tests.ts b/__tests__/widgets/oneTap/oneTap.tests.ts index 9e7191a..85dd1e0 100644 --- a/__tests__/widgets/oneTap/oneTap.tests.ts +++ b/__tests__/widgets/oneTap/oneTap.tests.ts @@ -1,10 +1,12 @@ -import { BridgeMessage } from '#/core/bridge'; import { BRIDGE_MESSAGE_TYPE_SDK } from '#/core/bridge/bridge'; import { WidgetEvents } from '#/core/widget'; -import { Config, Languages, OAuthName } from '#/index'; +import { Config, Languages, OAuthName, OneTapSkin } from '#/index'; import { Scheme } from '#/types'; import { OneTap } from '#/widgets/oneTap'; -import { OneTapInternalEvents } from '#/widgets/oneTap/events'; +import { OneTapBridgeMessage } from '#/widgets/oneTap/types'; + +import { WINDOW_LOCATION_URL } from '../../constants'; +import { wait } from '../../utils'; const APP_ID = 100; @@ -16,7 +18,7 @@ const openFn = jest.fn(); const removeEventListenerFn = jest.fn(); class TestOneTap extends OneTap { - public onBridgeMessageHandler(event: BridgeMessage) { + public onBridgeMessageHandler(event: OneTapBridgeMessage) { super.onBridgeMessageHandler(event); } } @@ -33,7 +35,7 @@ describe('OneTap', () => { }); beforeEach(() => { - Config.set({ app: APP_ID, redirectUrl: 'test', state: 'test' }); + Config.init({ app: APP_ID, redirectUrl: 'test', state: 'test', codeVerifier: 'codeVerifier' }); oneTap = new TestOneTap(); container = document.createElement('div', {}); @@ -45,7 +47,8 @@ describe('OneTap', () => { .addLabel('Platform', 'Web') .addLabel('Product', 'VK ID SDK') .addLabel('Component', 'OneTap') - .addLabel('Suite', 'Units'); + .addLabel('Suite', 'Units') + .addLabel('Project', 'VKIDSDK'); }); afterEach(() => { @@ -60,29 +63,31 @@ describe('OneTap', () => { expect(iframeElement).toBeTruthy(); const frameSrc = iframeElement.getAttribute('src') as string; - const location = frameSrc.split(/[?&]/); + const location = new URL(frameSrc); + const searchParams = new URLSearchParams(location.search); + + expect(location.href.split('?')[0]).toEqual('https://id.vk.com/button_one_tap_auth'); const expectArr = [ - expect(location[0]).toEqual('https://id.vk.com/button_one_tap_auth'), - expect(location[1]).toEqual('style_height=44'), - expect(location[2]).toEqual('style_border_radius=8'), - expect(location[3]).toEqual('show_alternative_login=1'), - expect(location[4]).toEqual('button_skin=primary'), - expect(location[5]).toEqual('scheme=light'), - expect(location[6]).toEqual('lang_id=0'), - expect(location[7]).toEqual('providers='), - expect(location[8]).toEqual('code_challenge=stringified_SHA256-STRING'), - expect(location[9]).toEqual('code_challenge_method=s256'), - expect(location[10]).toEqual('origin=https%3A%2F%2Frnd-service.ru'), - expect(frameSrc).toContain('uuid'), - expect(frameSrc).toContain('v'), - expect(location[13]).toEqual('sdk_type=vkid'), - expect(location[14]).toEqual('app_id=100'), - expect(location[15]).toEqual('redirect_uri=test'), - expect(location[16]).toEqual('redirect_state=test'), + expect(searchParams.get('style_height')).toEqual('44'), + expect(searchParams.get('style_border_radius')).toEqual('8'), + expect(searchParams.get('show_alternative_login')).toEqual('1'), + expect(searchParams.get('button_skin')).toEqual('primary'), + expect(searchParams.get('scheme')).toEqual('light'), + expect(searchParams.get('lang_id')).toEqual('0'), + expect(searchParams.get('providers')).toEqual(''), + expect(searchParams.get('origin')).toEqual(WINDOW_LOCATION_URL), + expect(searchParams.get('code_challenge')).toEqual('stringified_SHA256-STRING'), + expect(searchParams.get('code_challenge_method')).toEqual('s256'), + expect(searchParams.get('v')).toBeTruthy(), + expect(searchParams.get('sdk_type')).toEqual('vkid'), + expect(searchParams.get('app_id')).toEqual('100'), + expect(searchParams.get('redirect_uri')).toEqual('test'), + expect(searchParams.get('oauth_version')).toEqual('2'), + expect(searchParams.get('state')).toEqual(Config.get().state), ]; - expect(location.length).toEqual(expectArr.length); + expect([...new Set(searchParams.keys())].length).toEqual(expectArr.length); }); test('The lang_id parameter must be set', () => { @@ -110,7 +115,7 @@ describe('OneTap', () => { oneTap.render({ container, showAlternativeLogin: 1, - skin: 'secondary', + skin: OneTapSkin.Secondary, }); const oneTapEl = document.querySelector('[data-test-id="oneTap"]'); expect(oneTapEl?.getAttribute('data-scheme')).toEqual('light'); @@ -133,7 +138,7 @@ describe('OneTap', () => { container, showAlternativeLogin: 1, scheme: Scheme.DARK, - skin: 'secondary', + skin: OneTapSkin.Secondary, }); const oneTapEl = document.querySelector('[data-test-id="oneTap"]'); expect(oneTapEl?.getAttribute('data-scheme')).toEqual('dark'); @@ -158,7 +163,7 @@ describe('OneTap', () => { oneTap.onBridgeMessageHandler({ type: BRIDGE_MESSAGE_TYPE_SDK, handler: WidgetEvents.ERROR, - params: { someData: 'token' }, + params: { uuid: 'token' }, }); const oneTapEl = document.querySelector('[data-test-id="oneTap"]'); @@ -174,15 +179,11 @@ describe('OneTap', () => { oneTap.onBridgeMessageHandler({ type: BRIDGE_MESSAGE_TYPE_SDK, handler: WidgetEvents.LOAD, - params: { someData: 'token' }, + params: { uuid: 'token' }, }); const oneTapEl = document.querySelector('[data-test-id="oneTap"]'); - await new Promise((resolve) => { - setTimeout(() => { - resolve(''); - }, 400); - }); + await wait(400); expect(oneTapEl?.getAttribute('data-state')).toEqual('loaded'); }); @@ -191,11 +192,7 @@ describe('OneTap', () => { container, oauthList: [OAuthName.MAIL, OAuthName.OK], }); - await new Promise((resolve) => { - setTimeout(() => { - resolve(''); - }, 0); - }); + await wait(0); const oneTapEl = document.querySelector('[data-test-id="oneTap"]'); const oauthListEl = oneTapEl?.querySelector('[data-test-id="oauthList"]'); expect(oauthListEl).toBeTruthy(); @@ -206,11 +203,7 @@ describe('OneTap', () => { container, oauthList: [OAuthName.VK], }); - await new Promise((resolve) => { - setTimeout(() => { - resolve(''); - }, 0); - }); + await wait(0); const oneTapEl = document.querySelector('[data-test-id="oneTap"]'); const oauthListEl = oneTapEl?.querySelector('[data-test-id="oauthList"]'); expect(oauthListEl).toBeFalsy(); @@ -220,11 +213,7 @@ describe('OneTap', () => { oneTap.render({ container, }); - await new Promise((resolve) => { - setTimeout(() => { - resolve(''); - }, 0); - }); + await wait(0); const oneTapEl = document.querySelector('[data-test-id="oneTap"]'); const oauthListEl = oneTapEl?.querySelector('[data-test-id="oauthList"]'); expect(oauthListEl).toBeFalsy(); diff --git a/dangerfile.ts b/dangerfile.ts new file mode 100644 index 0000000..7e53bf3 --- /dev/null +++ b/dangerfile.ts @@ -0,0 +1,76 @@ +import { warn, message, danger } from "danger" +import * as fs from 'fs' +import { subtractObjects, makeCell } from './scripts/utilsMetrics.js' + +const targetBranchName = danger.gitlab.mr.target_branch; +if (!['master', 'develop'].includes(targetBranchName)) { + process.exit(0); +} + +const TARGET_METRICS_PATH = `.health-metrics/${targetBranchName}.json`; +const targetMetricsString = fs.readFileSync(TARGET_METRICS_PATH, 'utf-8'); +const targetMetrics = JSON.parse(targetMetricsString) || + { build: { esm: {}, cjs: {}, umd: {} }, tests: { coverage: {} } }; + +const BRANCH_METRICS_PATH = '.health-metrics/branch.json'; +const branchMetricsString = fs.readFileSync(BRANCH_METRICS_PATH, 'utf-8'); +const branchMetrics = JSON.parse(branchMetricsString); + +const diffMetrics = subtractObjects(branchMetrics, targetMetrics); + +const { coverage: branchCoverage, time: branchTime, passed: branchPassed, total: branchTotal, failed: branchFailed, skipped: branchSkipped } = branchMetrics.tests; +const { coverage: targetCoverage, time: targetTime, passed: targetPassed, total: targetTotal, failed: targetFailed, skipped: targetSkipped } = targetMetrics.tests; +const { coverage: diffCoverage, time: diffTime, passed: diffPassed, total: diffTotal, failed: diffFailed, skipped: diffSkipped } = diffMetrics.tests; + +// Docs edited start +const documentation = danger.git.fileMatch("docs/**/*"); +if (documentation.edited) { + warn("Публичный интерфейс был изменен!"); +} +// Docs edited end + +// Jest coverage start +const coverageMessage = ` +Code Coverage +| Lines | Statements | Functions | +| ------ | ------ | ------ | +` + + makeCell(branchCoverage.lines, targetCoverage.lines, diffCoverage.lines, '%') + + makeCell(branchCoverage.statements, targetCoverage.statements, diffCoverage.statements, '%') + + makeCell(branchCoverage.functions, targetCoverage.functions, diffCoverage.functions, '%') + '|'; +message(coverageMessage); +// Jest coverage end + +// Jest tests start +const testsStatusMessage = ` +Unit Tests Status +| Time | Passed | Failed | Skipped | Total | +| ------ | ------ | ------ | ------ | ------ | +` + + makeCell(branchTime, targetTime, diffTime, 's', true) + + makeCell(branchPassed, targetPassed, diffPassed) + + makeCell(branchFailed, targetFailed, diffFailed) + + makeCell(branchSkipped, targetSkipped, diffSkipped) + + makeCell(branchTotal, targetTotal, diffTotal) + '|'; +message(testsStatusMessage); +// Jest tests end + +// Build log start +const { esm: { time: esmBranchTime, size: esmBranchSize }, cjs: { time: cjsBranchTime, size: cjsBranchSize }, umd: { time: umdBranchTime, size: umdBranchSize } } = branchMetrics.build; +const { esm: { time: esmTargetTime, size: esmTargetSize }, cjs: { time: cjsTargetTime, size: cjsTargetSize }, umd: { time: umdTargetTime, size: umdTargetSize } } = targetMetrics.build; +const { esm: { time: esmDiffTime, size: esmDiffSize }, cjs: { time: cjsDiffTime, size: cjsDiffSize }, umd: { time: umdDiffTime, size: umdDiffSize } } = diffMetrics.build; + +const buildMessage = ` +Build Status +| | esm | cjs | umd | +| ------ | ------ | ------ | ------ | +| Size ` + + makeCell(esmBranchSize, esmTargetSize, esmDiffSize, 'b', true) + + makeCell(cjsBranchSize, cjsTargetSize, cjsDiffSize, 'b', true) + + makeCell(umdBranchSize, umdTargetSize, umdDiffSize, 'b', true) + ` +| Time ` + + makeCell(esmBranchTime, esmTargetTime, esmDiffTime, 'ms', true) + + makeCell(cjsBranchTime, cjsTargetTime, cjsDiffTime, 'ms', true) + + makeCell(umdBranchTime, umdTargetTime, umdDiffTime, 'ms', true) +message(buildMessage); +// Build log end diff --git a/demo/components/snackbar.ts b/demo/components/snackbar.ts index 81ce5e8..72caf07 100644 --- a/demo/components/snackbar.ts +++ b/demo/components/snackbar.ts @@ -65,7 +65,8 @@ export const showAuthSuccessSnackbar = () => { showSnackbar('auth_success'); }; -export const showAuthErrorSnackbar = () => { +export const showAuthErrorSnackbar = (e?: unknown) => { + e && console.error(e); showSnackbar('auth_error'); }; diff --git a/demo/index.ts b/demo/index.ts index 02783ec..79be5e0 100644 --- a/demo/index.ts +++ b/demo/index.ts @@ -1,28 +1,44 @@ import './styles.css'; import * as VKID from '@vkid/sdk'; +import { ConfigData } from '@vkid/sdk'; import { initHandleAuth } from './utils/handleAuth'; import { initAuthButtons } from './utils/initAuthButtons'; +import { initConfigParamsList } from './utils/initConfigParamsList'; import { initFloatingOneTap } from './utils/initFloatingOneTap'; import { initModuleEnabledList } from './utils/initModuleEnabledList'; import { initModuleParamsList } from './utils/initModuleParamsList'; import { initOauthList } from './utils/initOauthList'; import { initOneTap } from './utils/initOneTap'; -import { getDemoStoreFromLS, saveDemoStoreInLS } from './utils/localstorage'; +import { getDemoStoreFromLS, saveDemoStoreInLS, vkidDomainLS } from './utils/localstorage'; +import { initTokenManager } from './utils/tokenManager'; let demoStore = getDemoStoreFromLS(); /** * General settings */ -VKID.Config.set({ - app: 7303035, - state: 'test', +VKID.Config.init({ + app: +demoStore.app, + state: demoStore.state, + scope: demoStore.scope, + codeVerifier: demoStore.codeVerifier, redirectUrl: `${window.location.protocol}//${window.location.hostname}${window.location.pathname}`, mode: demoStore.mode, + prompt: demoStore.prompt, }); -initHandleAuth(); +if (demoStore.codeChallenge) { + VKID.Config.update({ codeChallenge: demoStore.codeChallenge }); +} + +const vkidDomain = vkidDomainLS(); +if (vkidDomain) { + VKID.Config.update({ __vkidDomain: vkidDomain }); +} + +initHandleAuth(demoStore); +initConfigParamsList(demoStore); initModuleParamsList(demoStore); initModuleEnabledList(demoStore); document.querySelector('html')?.setAttribute('data-scheme', demoStore.scheme); @@ -62,6 +78,8 @@ const resetOauthList = () => { } }; +initTokenManager(demoStore); + function handleSelectParamsChange() { demoStore = Object.assign(demoStore, { [this.name]: this.value }); saveDemoStoreInLS(demoStore); @@ -77,7 +95,7 @@ function handleSelectParamsChange() { }); function handleConfigParamsChange() { - VKID.Config.set({ + VKID.Config.update({ [this.name]: this.value, }); demoStore = Object.assign(demoStore, { [this.name]: this.value }); @@ -93,3 +111,38 @@ function handleModuleEnabledCheckboxChange() { ['enable_oauthList', 'enable_basicAuth', 'enable_oneTap', 'enable_floatingOneTap'].forEach((name) => { document.getElementById(name)?.addEventListener('change', handleModuleEnabledCheckboxChange); }); + +function handlePromptCheckboxChange() { + const promptRes: VKID.Prompt[] = []; + + const promptDiv = document.querySelector('.prompt'); + const promptInputs = promptDiv ? Array.from(promptDiv.getElementsByTagName('input')) : []; + promptInputs.forEach((input) => { + if (input.checked) { + promptRes.push(input.name as VKID.Prompt); + } + }); + + VKID.Config.update({ prompt: promptRes }); + demoStore = Object.assign(demoStore, { prompt: promptRes }); + saveDemoStoreInLS(demoStore); +} + +const promptDiv = document.querySelector('.prompt'); +const promptInputs = promptDiv ? Array.from(promptDiv.getElementsByTagName('input')) : []; +promptInputs.forEach((el) => { + el.addEventListener('change', handlePromptCheckboxChange); +}); + +function handleConfigInputChange(e: InputEvent) { + const target = e.target as HTMLInputElement; + const value = target.value; + const name = target.id.split('_')[1]; + demoStore = Object.assign(demoStore, { [name]: value }); + saveDemoStoreInLS(demoStore); + VKID.Config.update({ [name as keyof ConfigData]: value }); +} +['input_app', 'input_state', 'input_codeVerifier', 'input_codeChallenge', 'input_scope'].forEach((inputId) => { + document.getElementById(inputId)?.addEventListener('input', handleConfigInputChange); +}); + diff --git a/demo/styles.css b/demo/styles.css index 8645b6c..f5addb1 100644 --- a/demo/styles.css +++ b/demo/styles.css @@ -106,3 +106,25 @@ html[data-scheme="dark"] .VkIdWebSdk_controls { margin-top: 12px; } } + +.tokenManager_list { + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.tokenManager_user { + display: flex; + flex-direction: row; + align-items: center; +} + +.tokenManager_user > img { + margin-right: 12px; +} + +details > input { + width: 100%; + box-sizing: border-box; + margin-bottom: 8px; +} diff --git a/demo/types.ts b/demo/types.ts index 631f256..3d0d6dd 100644 --- a/demo/types.ts +++ b/demo/types.ts @@ -1,8 +1,13 @@ -import { ConfigAuthMode } from '#/core/config'; +import { TokenResult } from '#/auth/types'; +import { ConfigAuthMode, Prompt } from '#/core/config'; import { Languages, Scheme } from '#/types'; import { FloatingOneTapContentId } from '#/widgets/floatingOneTap'; export interface DemoStore { + app: number; + state: string; + codeVerifier: string; + codeChallenge: string; contentId: FloatingOneTapContentId; lang: Languages; scheme: Scheme; @@ -13,4 +18,9 @@ export interface DemoStore { enable_basicAuth: boolean; enable_oneTap: boolean; enable_floatingOneTap: boolean; + prompt: Prompt[]; + authResult?: TokenResult & { updated_at: Date }; + deviceId: string; + vkidDomain: string; + scope: string; } diff --git a/demo/utils/handleAuth.ts b/demo/utils/handleAuth.ts index 98ae0dc..dede963 100644 --- a/demo/utils/handleAuth.ts +++ b/demo/utils/handleAuth.ts @@ -1,17 +1,41 @@ +import { Auth } from '@vkid/sdk'; + +import { OAUTH2_CODE_TYPE } from '#/auth/constants'; + import { showAuthErrorSnackbar, showAuthSuccessSnackbar } from '#demo/components/snackbar'; +import { DemoStore } from '#demo/types'; +import { saveDemoStoreInLS } from '#demo/utils/localstorage'; +import { initTokenManager } from '#demo/utils/tokenManager'; -export const initHandleAuth = () => { +export const initHandleAuth = (demoStore: DemoStore) => { const urlParams = new URLSearchParams(window.location.search); try { - const payloadStr = urlParams.get('payload'); - if (payloadStr) { - const payload = JSON.parse(payloadStr); - if (payload && payload.token) { - showAuthSuccessSnackbar(); - window.history.pushState({}, document.title, window.location.pathname); - } else { - showAuthErrorSnackbar(); + const code = urlParams.get('code'); + const deviceId = urlParams.get('device_id'); + const error = urlParams.get('error'); + const responseType = urlParams.get('type'); + + if (deviceId && code && responseType === OAUTH2_CODE_TYPE) { + if (!demoStore.codeChallenge) { + Auth.exchangeCode(code, deviceId) + .then((exchangeRes) => { + Object.assign(demoStore, { authResult: { ...exchangeRes, updated_at: Date.now() }, deviceId }); + saveDemoStoreInLS(demoStore); + + // eslint-disable-next-line no-console + console.log('exchange auth code result:', exchangeRes); + showAuthSuccessSnackbar(); + + initTokenManager(demoStore); + }) + .catch((e) => { + console.error('Ошибка Auth.exchangeCode()', e); + showAuthErrorSnackbar(); + }); } + window.history.pushState({}, document.title, window.location.pathname); + } else if (error) { + showAuthErrorSnackbar(); } } catch {} }; diff --git a/demo/utils/initAuthButtons.ts b/demo/utils/initAuthButtons.ts index dcbaa41..edf29df 100644 --- a/demo/utils/initAuthButtons.ts +++ b/demo/utils/initAuthButtons.ts @@ -40,7 +40,12 @@ export const initAuthButtons = (demoStore: DemoStore) => { authButtonIds.forEach((item) => { const button = document.getElementById(item) as HTMLElement; - button.onclick = () => VKID.Auth.login(); + button.onclick = () => VKID.Auth.login({ + lang: demoStore.lang, + scheme: demoStore.scheme, + }).catch((e: VKID.AuthError) => { + console.error('Ошибка Auth.login()', e); + }); }); }; diff --git a/demo/utils/initConfigParamsList.ts b/demo/utils/initConfigParamsList.ts new file mode 100644 index 0000000..ce403a8 --- /dev/null +++ b/demo/utils/initConfigParamsList.ts @@ -0,0 +1,24 @@ +import { DemoStore } from '#demo/types'; + +export const initConfigParamsList = (store: DemoStore) => { + const html = `
+ Параметры конфига +
+ + +
+ + +
+ + +
+ + +
+ + +
+ `; + document.querySelector('.VkIdWebSdk_controls')?.insertAdjacentHTML('beforeend', html); +}; diff --git a/demo/utils/initModuleParamsList.ts b/demo/utils/initModuleParamsList.ts index b892bba..4b1a9fc 100644 --- a/demo/utils/initModuleParamsList.ts +++ b/demo/utils/initModuleParamsList.ts @@ -1,8 +1,13 @@ -import { Languages, Scheme, ConfigAuthMode, FloatingOneTapContentId, OneTapSkin, OAuthName } from '@vkid/sdk'; +import { Languages, Scheme, ConfigAuthMode, FloatingOneTapContentId, OneTapSkin, OAuthName, Prompt } from '@vkid/sdk'; + +import { DemoStore } from '#demo/types'; const langOptions = [ { value: Languages.RUS, text: 'RUS' }, { value: Languages.UKR, text: 'UKR' }, + { value: Languages.BEL, text: 'BEL' }, + { value: Languages.KAZ, text: 'KAZ' }, + { value: Languages.UZB, text: 'UZB' }, { value: Languages.ENG, text: 'ENG' }, { value: Languages.SPA, text: 'SPA' }, { value: Languages.GERMAN, text: 'GERMAN' }, @@ -42,7 +47,14 @@ const oauthesOptions = [ { value: OAuthName.MAIL + ',' + OAuthName.OK, text: 'Mail.ru + OK.ru' }, ]; -export const initModuleParamsList = (store: Record) => { +const promptOptions = [ + { value: Prompt.Login, text: 'Login' }, + { value: Prompt.Consent, text: 'Consent' }, + { value: Prompt.None, text: 'None' }, + { value: Prompt.SelectAccount, text: 'Select account' }, +]; + +export const initModuleParamsList = (store: DemoStore) => { const html = `
Параметры модулей @@ -75,6 +87,14 @@ export const initModuleParamsList = (store: Record) => { ${oauthesOptions.map(({ text, value }) => ``).join('')}
+
+
+ Prompt + ${promptOptions.map(({ text, value }) => `
`).join('')} +
+
+
`; diff --git a/demo/utils/localstorage.ts b/demo/utils/localstorage.ts index 19d830b..2838796 100644 --- a/demo/utils/localstorage.ts +++ b/demo/utils/localstorage.ts @@ -9,8 +9,22 @@ export const saveDemoStoreInLS = (store: DemoStore) => { } catch (e) {} }; +export const vkidDomainLS = (domain?: string) => { + try { + if (domain) { + localStorage.setItem('vkid_demo:vkidDomain', domain); + return; + } + return localStorage.getItem('vkid_demo:vkidDomain'); + } catch (e) {} +}; + export const getDemoStoreFromLS = (): DemoStore => { const defaultDemoStore: DemoStore = { + app: 7303035, + state: '', + codeVerifier: '', + codeChallenge: '', contentId: VKID.FloatingOneTapContentId.SIGN_IN_TO_SERVICE, lang: VKID.Languages.RUS, scheme: VKID.Scheme.LIGHT, @@ -22,12 +36,17 @@ export const getDemoStoreFromLS = (): DemoStore => { enable_basicAuth: true, enable_oneTap: true, enable_floatingOneTap: true, + prompt: [], + deviceId: '', + vkidDomain: '', + scope: '', }; try { const stringStore = localStorage.getItem('vkid_demo:store'); if (stringStore) { - return JSON.parse(stringStore); + const lsStore = JSON.parse(stringStore); + return { ...defaultDemoStore, ...lsStore }; } saveDemoStoreInLS(defaultDemoStore); } catch (e) {} diff --git a/demo/utils/tokenManager.ts b/demo/utils/tokenManager.ts new file mode 100644 index 0000000..e173db5 --- /dev/null +++ b/demo/utils/tokenManager.ts @@ -0,0 +1,106 @@ +import * as VKID from '#/index'; + +import { DemoStore } from '#demo/types'; +import { saveDemoStoreInLS } from '#demo/utils/localstorage'; + +export const initTokenManager = (demoStore: DemoStore) => { + const tokenManagerSectionElement = document.querySelector('.tokenManager'); + if (tokenManagerSectionElement) { + tokenManagerSectionElement.remove(); + } + const html = `
+

Последнее обновление: ${new Date(demoStore.authResult?.updated_at || 0).toUTCString()}

+
+ AT: ${demoStore.authResult?.access_token?.slice(0, 15)}... + RT: ${demoStore.authResult?.refresh_token?.slice(0, 15)}... + IDT: ${demoStore.authResult?.id_token?.slice(0, 15)}... +
+
+ + + + +
+
+avatar + +
+
+`; + if (!demoStore.authResult) { + return; + } + + document.querySelector('.VkIdWebSdk__content')?.insertAdjacentHTML('beforeend', html); + + const refreshButtonElement = document.getElementById('tokenManager_button_refresh'); + if (refreshButtonElement) { + refreshButtonElement.onclick = () => { + VKID.Auth.refreshToken(demoStore.authResult?.refresh_token || '', demoStore.deviceId) + .then((result) => { + const authResult = demoStore.authResult || {}; + Object.assign(authResult, { ...result, updated_at: Date.now() }); + Object.assign(demoStore, { authResult }); + saveDemoStoreInLS(demoStore); + + // eslint-disable-next-line no-console + console.log('refresh token result:', result); + initTokenManager(demoStore); + }) + .catch((e) => console.error('refresh token error:', e)); + }; + } + + const logoutButtonElement = document.getElementById('tokenManager_button_logout'); + if (logoutButtonElement) { + logoutButtonElement.onclick = () => { + VKID.Auth.logout(demoStore.authResult?.access_token || '') + .then((res) => { + // eslint-disable-next-line no-console + console.log('invalidate AT:', demoStore.authResult?.access_token?.slice(0, 8), res); + initTokenManager(demoStore); + }) + .catch((e) => console.error('logout error:', e)); + }; + } + + const publicInfoButtonElement = document.getElementById('tokenManager_button_idt'); + if (publicInfoButtonElement) { + publicInfoButtonElement.onclick = () => { + VKID.Auth.publicInfo(demoStore.authResult?.id_token || '') + .then((res) => { + // eslint-disable-next-line no-console + console.log('public_info id_token result:', res); + + const user = res.user; + const userElement = document.getElementById('tokenManager_user_name'); + const avatarElement = document.getElementById('tokenManager_user_avatar'); + if (userElement && avatarElement) { + userElement.innerText = `${user.first_name} ${user.last_name}, ${user.phone}, ${user.email}`; + avatarElement.setAttribute('src', user.avatar); + } + }) + .catch((e) => console.error('public_info error:', e)); + }; + } + + const userInfoButtonElement = document.getElementById('tokenManager_button_at'); + if (userInfoButtonElement) { + userInfoButtonElement.onclick = () => { + VKID.Auth.userInfo(demoStore.authResult?.access_token || '') + .then((res) => { + // eslint-disable-next-line no-console + console.log('user_info access_token result:', res); + + const user = res.user; + const userElement = document.getElementById('tokenManager_user_name'); + const avatarElement = document.getElementById('tokenManager_user_avatar'); + if (userElement && avatarElement) { + userElement.innerText = `${user.first_name} ${user.last_name}, ${user.phone}, ${user.email}`; + avatarElement.setAttribute('src', user.avatar || ''); + } + }) + .catch((e) => console.error('user_info error:', e)); + }; + } +}; diff --git a/docs/assets/search.js b/docs/assets/search.js index 1a555b4..c8d81d3 100644 --- a/docs/assets/search.js +++ b/docs/assets/search.js @@ -1 +1 @@ -window.searchData = JSON.parse("{\"rows\":[{\"kind\":2,\"name\":\"core/config\",\"url\":\"modules/core_config.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"auth\",\"url\":\"modules/auth.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"widgets/oneTap\",\"url\":\"modules/widgets_oneTap.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"widgets/floatingOneTap\",\"url\":\"modules/widgets_floatingOneTap.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"widgets/oauthList\",\"url\":\"modules/widgets_oauthList.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"types\",\"url\":\"modules/types.html\",\"classes\":\"\"},{\"kind\":8,\"name\":\"Languages\",\"url\":\"enums/types.Languages.html\",\"classes\":\"\",\"parent\":\"types\"},{\"kind\":16,\"name\":\"RUS\",\"url\":\"enums/types.Languages.html#RUS\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"UKR\",\"url\":\"enums/types.Languages.html#UKR\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"ENG\",\"url\":\"enums/types.Languages.html#ENG\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"SPA\",\"url\":\"enums/types.Languages.html#SPA\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"GERMAN\",\"url\":\"enums/types.Languages.html#GERMAN\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"POL\",\"url\":\"enums/types.Languages.html#POL\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"FRA\",\"url\":\"enums/types.Languages.html#FRA\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"TURKEY\",\"url\":\"enums/types.Languages.html#TURKEY\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":8,\"name\":\"Scheme\",\"url\":\"enums/types.Scheme.html\",\"classes\":\"\",\"parent\":\"types\"},{\"kind\":16,\"name\":\"LIGHT\",\"url\":\"enums/types.Scheme.html#LIGHT\",\"classes\":\"\",\"parent\":\"types.Scheme\"},{\"kind\":16,\"name\":\"DARK\",\"url\":\"enums/types.Scheme.html#DARK\",\"classes\":\"\",\"parent\":\"types.Scheme\"},{\"kind\":128,\"name\":\"Config\",\"url\":\"classes/core_config.Config.html\",\"classes\":\"\",\"parent\":\"core/config\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/core_config.Config.html#constructor\",\"classes\":\"\",\"parent\":\"core/config.Config\"},{\"kind\":2048,\"name\":\"set\",\"url\":\"classes/core_config.Config.html#set\",\"classes\":\"\",\"parent\":\"core/config.Config\"},{\"kind\":2048,\"name\":\"get\",\"url\":\"classes/core_config.Config.html#get\",\"classes\":\"\",\"parent\":\"core/config.Config\"},{\"kind\":8,\"name\":\"ConfigAuthMode\",\"url\":\"enums/core_config.ConfigAuthMode.html\",\"classes\":\"\",\"parent\":\"core/config\"},{\"kind\":16,\"name\":\"Redirect\",\"url\":\"enums/core_config.ConfigAuthMode.html#Redirect\",\"classes\":\"\",\"parent\":\"core/config.ConfigAuthMode\"},{\"kind\":16,\"name\":\"InNewTab\",\"url\":\"enums/core_config.ConfigAuthMode.html#InNewTab\",\"classes\":\"\",\"parent\":\"core/config.ConfigAuthMode\"},{\"kind\":256,\"name\":\"ConfigData\",\"url\":\"interfaces/core_config.ConfigData.html\",\"classes\":\"\",\"parent\":\"core/config\"},{\"kind\":1024,\"name\":\"app\",\"url\":\"interfaces/core_config.ConfigData.html#app\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":1024,\"name\":\"redirectUrl\",\"url\":\"interfaces/core_config.ConfigData.html#redirectUrl\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":1024,\"name\":\"state\",\"url\":\"interfaces/core_config.ConfigData.html#state\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":1024,\"name\":\"mode\",\"url\":\"interfaces/core_config.ConfigData.html#mode\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":128,\"name\":\"Auth\",\"url\":\"classes/auth.Auth.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/auth.Auth.html#constructor\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":2048,\"name\":\"login\",\"url\":\"classes/auth.Auth.html#login\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":8,\"name\":\"AuthErrorCode\",\"url\":\"enums/auth.AuthErrorCode.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":16,\"name\":\"EventNotSupported\",\"url\":\"enums/auth.AuthErrorCode.html#EventNotSupported\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":16,\"name\":\"CannotCreateNewTab\",\"url\":\"enums/auth.AuthErrorCode.html#CannotCreateNewTab\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":16,\"name\":\"NewTabHasBeenClosed\",\"url\":\"enums/auth.AuthErrorCode.html#NewTabHasBeenClosed\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":16,\"name\":\"AuthorizationFailed\",\"url\":\"enums/auth.AuthErrorCode.html#AuthorizationFailed\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":256,\"name\":\"AuthParams\",\"url\":\"interfaces/auth.AuthParams.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"scheme\",\"url\":\"interfaces/auth.AuthParams.html#scheme\",\"classes\":\"\",\"parent\":\"auth.AuthParams\"},{\"kind\":1024,\"name\":\"lang\",\"url\":\"interfaces/auth.AuthParams.html#lang\",\"classes\":\"\",\"parent\":\"auth.AuthParams\"},{\"kind\":256,\"name\":\"AuthError\",\"url\":\"interfaces/auth.AuthError.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"code\",\"url\":\"interfaces/auth.AuthError.html#code\",\"classes\":\"\",\"parent\":\"auth.AuthError\"},{\"kind\":1024,\"name\":\"text\",\"url\":\"interfaces/auth.AuthError.html#text\",\"classes\":\"\",\"parent\":\"auth.AuthError\"},{\"kind\":1024,\"name\":\"details\",\"url\":\"interfaces/auth.AuthError.html#details\",\"classes\":\"\",\"parent\":\"auth.AuthError\"},{\"kind\":256,\"name\":\"AuthResponse\",\"url\":\"interfaces/auth.AuthResponse.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"token\",\"url\":\"interfaces/auth.AuthResponse.html#token\",\"classes\":\"\",\"parent\":\"auth.AuthResponse\"},{\"kind\":1024,\"name\":\"type\",\"url\":\"interfaces/auth.AuthResponse.html#type\",\"classes\":\"\",\"parent\":\"auth.AuthResponse\"},{\"kind\":1024,\"name\":\"ttl\",\"url\":\"interfaces/auth.AuthResponse.html#ttl\",\"classes\":\"\",\"parent\":\"auth.AuthResponse\"},{\"kind\":128,\"name\":\"OneTap\",\"url\":\"classes/widgets_oneTap.OneTap.html\",\"classes\":\"\",\"parent\":\"widgets/oneTap\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/widgets_oneTap.OneTap.html#constructor\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"render\",\"url\":\"classes/widgets_oneTap.OneTap.html#render\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"close\",\"url\":\"classes/widgets_oneTap.OneTap.html#close\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"show\",\"url\":\"classes/widgets_oneTap.OneTap.html#show\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"hide\",\"url\":\"classes/widgets_oneTap.OneTap.html#hide\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"on\",\"url\":\"classes/widgets_oneTap.OneTap.html#on\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"off\",\"url\":\"classes/widgets_oneTap.OneTap.html#off\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":256,\"name\":\"OneTapParams\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html\",\"classes\":\"\",\"parent\":\"widgets/oneTap\"},{\"kind\":1024,\"name\":\"showAlternativeLogin\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#showAlternativeLogin\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"styles\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#styles\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"skin\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#skin\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"oauthList\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#oauthList\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"container\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#container\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"scheme\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#scheme\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"lang\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#lang\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":256,\"name\":\"OneTapStyles\",\"url\":\"interfaces/widgets_oneTap.OneTapStyles.html\",\"classes\":\"\",\"parent\":\"widgets/oneTap\"},{\"kind\":1024,\"name\":\"width\",\"url\":\"interfaces/widgets_oneTap.OneTapStyles.html#width\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapStyles\"},{\"kind\":1024,\"name\":\"height\",\"url\":\"interfaces/widgets_oneTap.OneTapStyles.html#height\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapStyles\"},{\"kind\":1024,\"name\":\"borderRadius\",\"url\":\"interfaces/widgets_oneTap.OneTapStyles.html#borderRadius\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapStyles\"},{\"kind\":8,\"name\":\"OneTapSkin\",\"url\":\"enums/widgets_oneTap.OneTapSkin.html\",\"classes\":\"\",\"parent\":\"widgets/oneTap\"},{\"kind\":16,\"name\":\"Primary\",\"url\":\"enums/widgets_oneTap.OneTapSkin.html#Primary\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapSkin\"},{\"kind\":16,\"name\":\"Secondary\",\"url\":\"enums/widgets_oneTap.OneTapSkin.html#Secondary\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapSkin\"},{\"kind\":128,\"name\":\"FloatingOneTap\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#constructor\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"render\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#render\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"close\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#close\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"show\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#show\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"hide\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#hide\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"on\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#on\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"off\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#off\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":256,\"name\":\"FloatingOneTapParams\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap\"},{\"kind\":1024,\"name\":\"indent\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#indent\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"contentId\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#contentId\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"showAlternativeLogin\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#showAlternativeLogin\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"appName\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#appName\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"oauthList\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#oauthList\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"lang\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#lang\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"scheme\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#scheme\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":8,\"name\":\"FloatingOneTapContentId\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap\"},{\"kind\":16,\"name\":\"SIGN_IN_TO_SERVICE\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#SIGN_IN_TO_SERVICE\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"SIGN_IN_TO_ACCOUNT\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#SIGN_IN_TO_ACCOUNT\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"REGISTRATION_FOR_EVENT\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#REGISTRATION_FOR_EVENT\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"SUBMIT_APPLICATIONS\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#SUBMIT_APPLICATIONS\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"MAKE_ORDER_WITH_SERVICE\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#MAKE_ORDER_WITH_SERVICE\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"MAKE_ORDER_WITHOUT_SERVICE\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#MAKE_ORDER_WITHOUT_SERVICE\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":256,\"name\":\"FloatingOneTapIndent\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap\"},{\"kind\":1024,\"name\":\"top\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html#top\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapIndent\"},{\"kind\":1024,\"name\":\"right\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html#right\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapIndent\"},{\"kind\":1024,\"name\":\"bottom\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html#bottom\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapIndent\"},{\"kind\":128,\"name\":\"OAuthList\",\"url\":\"classes/widgets_oauthList.OAuthList.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/widgets_oauthList.OAuthList.html#constructor\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"render\",\"url\":\"classes/widgets_oauthList.OAuthList.html#render\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"close\",\"url\":\"classes/widgets_oauthList.OAuthList.html#close\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"show\",\"url\":\"classes/widgets_oauthList.OAuthList.html#show\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"hide\",\"url\":\"classes/widgets_oauthList.OAuthList.html#hide\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"on\",\"url\":\"classes/widgets_oauthList.OAuthList.html#on\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"off\",\"url\":\"classes/widgets_oauthList.OAuthList.html#off\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":256,\"name\":\"OAuthListParams\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":1024,\"name\":\"styles\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#styles\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":1024,\"name\":\"oauthList\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#oauthList\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":1024,\"name\":\"container\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#container\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":1024,\"name\":\"scheme\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#scheme\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":1024,\"name\":\"lang\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#lang\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":8,\"name\":\"OAuthName\",\"url\":\"enums/widgets_oauthList.OAuthName.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":16,\"name\":\"OK\",\"url\":\"enums/widgets_oauthList.OAuthName.html#OK\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthName\"},{\"kind\":16,\"name\":\"MAIL\",\"url\":\"enums/widgets_oauthList.OAuthName.html#MAIL\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthName\"},{\"kind\":16,\"name\":\"VK\",\"url\":\"enums/widgets_oauthList.OAuthName.html#VK\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthName\"},{\"kind\":256,\"name\":\"OAuthListStyles\",\"url\":\"interfaces/widgets_oauthList.OAuthListStyles.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":1024,\"name\":\"height\",\"url\":\"interfaces/widgets_oauthList.OAuthListStyles.html#height\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthListStyles\"},{\"kind\":1024,\"name\":\"borderRadius\",\"url\":\"interfaces/widgets_oauthList.OAuthListStyles.html#borderRadius\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthListStyles\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"comment\"],\"fieldVectors\":[[\"name/0\",[0,43.903]],[\"comment/0\",[]],[\"name/1\",[1,38.795]],[\"comment/1\",[]],[\"name/2\",[2,43.903]],[\"comment/2\",[]],[\"name/3\",[3,43.903]],[\"comment/3\",[]],[\"name/4\",[4,43.903]],[\"comment/4\",[]],[\"name/5\",[5,43.903]],[\"comment/5\",[]],[\"name/6\",[6,43.903]],[\"comment/6\",[]],[\"name/7\",[7,43.903]],[\"comment/7\",[]],[\"name/8\",[8,43.903]],[\"comment/8\",[]],[\"name/9\",[9,43.903]],[\"comment/9\",[]],[\"name/10\",[10,43.903]],[\"comment/10\",[]],[\"name/11\",[11,43.903]],[\"comment/11\",[]],[\"name/12\",[12,43.903]],[\"comment/12\",[]],[\"name/13\",[13,43.903]],[\"comment/13\",[]],[\"name/14\",[14,43.903]],[\"comment/14\",[]],[\"name/15\",[15,30.91]],[\"comment/15\",[]],[\"name/16\",[16,43.903]],[\"comment/16\",[]],[\"name/17\",[17,43.903]],[\"comment/17\",[]],[\"name/18\",[18,43.903]],[\"comment/18\",[]],[\"name/19\",[19,30.91]],[\"comment/19\",[]],[\"name/20\",[20,43.903]],[\"comment/20\",[]],[\"name/21\",[21,43.903]],[\"comment/21\",[]],[\"name/22\",[22,43.903]],[\"comment/22\",[]],[\"name/23\",[23,43.903]],[\"comment/23\",[]],[\"name/24\",[24,43.903]],[\"comment/24\",[]],[\"name/25\",[25,43.903]],[\"comment/25\",[]],[\"name/26\",[26,43.903]],[\"comment/26\",[]],[\"name/27\",[27,43.903]],[\"comment/27\",[]],[\"name/28\",[28,43.903]],[\"comment/28\",[]],[\"name/29\",[29,43.903]],[\"comment/29\",[]],[\"name/30\",[1,38.795]],[\"comment/30\",[]],[\"name/31\",[19,30.91]],[\"comment/31\",[]],[\"name/32\",[30,43.903]],[\"comment/32\",[]],[\"name/33\",[31,43.903]],[\"comment/33\",[]],[\"name/34\",[32,43.903]],[\"comment/34\",[]],[\"name/35\",[33,43.903]],[\"comment/35\",[]],[\"name/36\",[34,43.903]],[\"comment/36\",[]],[\"name/37\",[35,43.903]],[\"comment/37\",[]],[\"name/38\",[36,43.903]],[\"comment/38\",[]],[\"name/39\",[15,30.91]],[\"comment/39\",[]],[\"name/40\",[37,32.917]],[\"comment/40\",[]],[\"name/41\",[38,43.903]],[\"comment/41\",[]],[\"name/42\",[39,43.903]],[\"comment/42\",[]],[\"name/43\",[40,43.903]],[\"comment/43\",[]],[\"name/44\",[41,43.903]],[\"comment/44\",[]],[\"name/45\",[42,43.903]],[\"comment/45\",[]],[\"name/46\",[43,43.903]],[\"comment/46\",[]],[\"name/47\",[44,43.903]],[\"comment/47\",[]],[\"name/48\",[45,43.903]],[\"comment/48\",[]],[\"name/49\",[46,43.903]],[\"comment/49\",[]],[\"name/50\",[19,30.91]],[\"comment/50\",[]],[\"name/51\",[47,35.43]],[\"comment/51\",[]],[\"name/52\",[48,35.43]],[\"comment/52\",[]],[\"name/53\",[49,35.43]],[\"comment/53\",[]],[\"name/54\",[50,35.43]],[\"comment/54\",[]],[\"name/55\",[51,35.43]],[\"comment/55\",[]],[\"name/56\",[52,35.43]],[\"comment/56\",[]],[\"name/57\",[53,43.903]],[\"comment/57\",[]],[\"name/58\",[54,38.795]],[\"comment/58\",[]],[\"name/59\",[55,38.795]],[\"comment/59\",[]],[\"name/60\",[56,43.903]],[\"comment/60\",[]],[\"name/61\",[57,32.917]],[\"comment/61\",[]],[\"name/62\",[58,38.795]],[\"comment/62\",[]],[\"name/63\",[15,30.91]],[\"comment/63\",[]],[\"name/64\",[37,32.917]],[\"comment/64\",[]],[\"name/65\",[59,43.903]],[\"comment/65\",[]],[\"name/66\",[60,43.903]],[\"comment/66\",[]],[\"name/67\",[61,38.795]],[\"comment/67\",[]],[\"name/68\",[62,38.795]],[\"comment/68\",[]],[\"name/69\",[63,43.903]],[\"comment/69\",[]],[\"name/70\",[64,43.903]],[\"comment/70\",[]],[\"name/71\",[65,43.903]],[\"comment/71\",[]],[\"name/72\",[66,43.903]],[\"comment/72\",[]],[\"name/73\",[19,30.91]],[\"comment/73\",[]],[\"name/74\",[47,35.43]],[\"comment/74\",[]],[\"name/75\",[48,35.43]],[\"comment/75\",[]],[\"name/76\",[49,35.43]],[\"comment/76\",[]],[\"name/77\",[50,35.43]],[\"comment/77\",[]],[\"name/78\",[51,35.43]],[\"comment/78\",[]],[\"name/79\",[52,35.43]],[\"comment/79\",[]],[\"name/80\",[67,43.903]],[\"comment/80\",[]],[\"name/81\",[68,43.903]],[\"comment/81\",[]],[\"name/82\",[69,43.903]],[\"comment/82\",[]],[\"name/83\",[54,38.795]],[\"comment/83\",[]],[\"name/84\",[70,43.903]],[\"comment/84\",[]],[\"name/85\",[57,32.917]],[\"comment/85\",[]],[\"name/86\",[37,32.917]],[\"comment/86\",[]],[\"name/87\",[15,30.91]],[\"comment/87\",[]],[\"name/88\",[71,43.903]],[\"comment/88\",[]],[\"name/89\",[72,43.903]],[\"comment/89\",[]],[\"name/90\",[73,43.903]],[\"comment/90\",[]],[\"name/91\",[74,43.903]],[\"comment/91\",[]],[\"name/92\",[75,43.903]],[\"comment/92\",[]],[\"name/93\",[76,43.903]],[\"comment/93\",[]],[\"name/94\",[77,43.903]],[\"comment/94\",[]],[\"name/95\",[78,43.903]],[\"comment/95\",[]],[\"name/96\",[79,43.903]],[\"comment/96\",[]],[\"name/97\",[80,43.903]],[\"comment/97\",[]],[\"name/98\",[81,43.903]],[\"comment/98\",[]],[\"name/99\",[57,32.917]],[\"comment/99\",[]],[\"name/100\",[19,30.91]],[\"comment/100\",[]],[\"name/101\",[47,35.43]],[\"comment/101\",[]],[\"name/102\",[48,35.43]],[\"comment/102\",[]],[\"name/103\",[49,35.43]],[\"comment/103\",[]],[\"name/104\",[50,35.43]],[\"comment/104\",[]],[\"name/105\",[51,35.43]],[\"comment/105\",[]],[\"name/106\",[52,35.43]],[\"comment/106\",[]],[\"name/107\",[82,43.903]],[\"comment/107\",[]],[\"name/108\",[55,38.795]],[\"comment/108\",[]],[\"name/109\",[57,32.917]],[\"comment/109\",[]],[\"name/110\",[58,38.795]],[\"comment/110\",[]],[\"name/111\",[15,30.91]],[\"comment/111\",[]],[\"name/112\",[37,32.917]],[\"comment/112\",[]],[\"name/113\",[83,43.903]],[\"comment/113\",[]],[\"name/114\",[84,43.903]],[\"comment/114\",[]],[\"name/115\",[85,43.903]],[\"comment/115\",[]],[\"name/116\",[86,43.903]],[\"comment/116\",[]],[\"name/117\",[87,43.903]],[\"comment/117\",[]],[\"name/118\",[61,38.795]],[\"comment/118\",[]],[\"name/119\",[62,38.795]],[\"comment/119\",[]]],\"invertedIndex\":[[\"app\",{\"_index\":26,\"name\":{\"26\":{}},\"comment\":{}}],[\"appname\",{\"_index\":70,\"name\":{\"84\":{}},\"comment\":{}}],[\"auth\",{\"_index\":1,\"name\":{\"1\":{},\"30\":{}},\"comment\":{}}],[\"autherror\",{\"_index\":38,\"name\":{\"41\":{}},\"comment\":{}}],[\"autherrorcode\",{\"_index\":31,\"name\":{\"33\":{}},\"comment\":{}}],[\"authorizationfailed\",{\"_index\":35,\"name\":{\"37\":{}},\"comment\":{}}],[\"authparams\",{\"_index\":36,\"name\":{\"38\":{}},\"comment\":{}}],[\"authresponse\",{\"_index\":42,\"name\":{\"45\":{}},\"comment\":{}}],[\"borderradius\",{\"_index\":62,\"name\":{\"68\":{},\"119\":{}},\"comment\":{}}],[\"bottom\",{\"_index\":81,\"name\":{\"98\":{}},\"comment\":{}}],[\"cannotcreatenewtab\",{\"_index\":33,\"name\":{\"35\":{}},\"comment\":{}}],[\"close\",{\"_index\":48,\"name\":{\"52\":{},\"75\":{},\"102\":{}},\"comment\":{}}],[\"code\",{\"_index\":39,\"name\":{\"42\":{}},\"comment\":{}}],[\"config\",{\"_index\":18,\"name\":{\"18\":{}},\"comment\":{}}],[\"configauthmode\",{\"_index\":22,\"name\":{\"22\":{}},\"comment\":{}}],[\"configdata\",{\"_index\":25,\"name\":{\"25\":{}},\"comment\":{}}],[\"constructor\",{\"_index\":19,\"name\":{\"19\":{},\"31\":{},\"50\":{},\"73\":{},\"100\":{}},\"comment\":{}}],[\"container\",{\"_index\":58,\"name\":{\"62\":{},\"110\":{}},\"comment\":{}}],[\"contentid\",{\"_index\":69,\"name\":{\"82\":{}},\"comment\":{}}],[\"core/config\",{\"_index\":0,\"name\":{\"0\":{}},\"comment\":{}}],[\"dark\",{\"_index\":17,\"name\":{\"17\":{}},\"comment\":{}}],[\"details\",{\"_index\":41,\"name\":{\"44\":{}},\"comment\":{}}],[\"eng\",{\"_index\":9,\"name\":{\"9\":{}},\"comment\":{}}],[\"eventnotsupported\",{\"_index\":32,\"name\":{\"34\":{}},\"comment\":{}}],[\"floatingonetap\",{\"_index\":66,\"name\":{\"72\":{}},\"comment\":{}}],[\"floatingonetapcontentid\",{\"_index\":71,\"name\":{\"88\":{}},\"comment\":{}}],[\"floatingonetapindent\",{\"_index\":78,\"name\":{\"95\":{}},\"comment\":{}}],[\"floatingonetapparams\",{\"_index\":67,\"name\":{\"80\":{}},\"comment\":{}}],[\"fra\",{\"_index\":13,\"name\":{\"13\":{}},\"comment\":{}}],[\"german\",{\"_index\":11,\"name\":{\"11\":{}},\"comment\":{}}],[\"get\",{\"_index\":21,\"name\":{\"21\":{}},\"comment\":{}}],[\"height\",{\"_index\":61,\"name\":{\"67\":{},\"118\":{}},\"comment\":{}}],[\"hide\",{\"_index\":50,\"name\":{\"54\":{},\"77\":{},\"104\":{}},\"comment\":{}}],[\"indent\",{\"_index\":68,\"name\":{\"81\":{}},\"comment\":{}}],[\"innewtab\",{\"_index\":24,\"name\":{\"24\":{}},\"comment\":{}}],[\"lang\",{\"_index\":37,\"name\":{\"40\":{},\"64\":{},\"86\":{},\"112\":{}},\"comment\":{}}],[\"languages\",{\"_index\":6,\"name\":{\"6\":{}},\"comment\":{}}],[\"light\",{\"_index\":16,\"name\":{\"16\":{}},\"comment\":{}}],[\"login\",{\"_index\":30,\"name\":{\"32\":{}},\"comment\":{}}],[\"mail\",{\"_index\":85,\"name\":{\"115\":{}},\"comment\":{}}],[\"make_order_with_service\",{\"_index\":76,\"name\":{\"93\":{}},\"comment\":{}}],[\"make_order_without_service\",{\"_index\":77,\"name\":{\"94\":{}},\"comment\":{}}],[\"mode\",{\"_index\":29,\"name\":{\"29\":{}},\"comment\":{}}],[\"newtabhasbeenclosed\",{\"_index\":34,\"name\":{\"36\":{}},\"comment\":{}}],[\"oauthlist\",{\"_index\":57,\"name\":{\"61\":{},\"85\":{},\"99\":{},\"109\":{}},\"comment\":{}}],[\"oauthlistparams\",{\"_index\":82,\"name\":{\"107\":{}},\"comment\":{}}],[\"oauthliststyles\",{\"_index\":87,\"name\":{\"117\":{}},\"comment\":{}}],[\"oauthname\",{\"_index\":83,\"name\":{\"113\":{}},\"comment\":{}}],[\"off\",{\"_index\":52,\"name\":{\"56\":{},\"79\":{},\"106\":{}},\"comment\":{}}],[\"ok\",{\"_index\":84,\"name\":{\"114\":{}},\"comment\":{}}],[\"on\",{\"_index\":51,\"name\":{\"55\":{},\"78\":{},\"105\":{}},\"comment\":{}}],[\"onetap\",{\"_index\":46,\"name\":{\"49\":{}},\"comment\":{}}],[\"onetapparams\",{\"_index\":53,\"name\":{\"57\":{}},\"comment\":{}}],[\"onetapskin\",{\"_index\":63,\"name\":{\"69\":{}},\"comment\":{}}],[\"onetapstyles\",{\"_index\":59,\"name\":{\"65\":{}},\"comment\":{}}],[\"pol\",{\"_index\":12,\"name\":{\"12\":{}},\"comment\":{}}],[\"primary\",{\"_index\":64,\"name\":{\"70\":{}},\"comment\":{}}],[\"redirect\",{\"_index\":23,\"name\":{\"23\":{}},\"comment\":{}}],[\"redirecturl\",{\"_index\":27,\"name\":{\"27\":{}},\"comment\":{}}],[\"registration_for_event\",{\"_index\":74,\"name\":{\"91\":{}},\"comment\":{}}],[\"render\",{\"_index\":47,\"name\":{\"51\":{},\"74\":{},\"101\":{}},\"comment\":{}}],[\"right\",{\"_index\":80,\"name\":{\"97\":{}},\"comment\":{}}],[\"rus\",{\"_index\":7,\"name\":{\"7\":{}},\"comment\":{}}],[\"scheme\",{\"_index\":15,\"name\":{\"15\":{},\"39\":{},\"63\":{},\"87\":{},\"111\":{}},\"comment\":{}}],[\"secondary\",{\"_index\":65,\"name\":{\"71\":{}},\"comment\":{}}],[\"set\",{\"_index\":20,\"name\":{\"20\":{}},\"comment\":{}}],[\"show\",{\"_index\":49,\"name\":{\"53\":{},\"76\":{},\"103\":{}},\"comment\":{}}],[\"showalternativelogin\",{\"_index\":54,\"name\":{\"58\":{},\"83\":{}},\"comment\":{}}],[\"sign_in_to_account\",{\"_index\":73,\"name\":{\"90\":{}},\"comment\":{}}],[\"sign_in_to_service\",{\"_index\":72,\"name\":{\"89\":{}},\"comment\":{}}],[\"skin\",{\"_index\":56,\"name\":{\"60\":{}},\"comment\":{}}],[\"spa\",{\"_index\":10,\"name\":{\"10\":{}},\"comment\":{}}],[\"state\",{\"_index\":28,\"name\":{\"28\":{}},\"comment\":{}}],[\"styles\",{\"_index\":55,\"name\":{\"59\":{},\"108\":{}},\"comment\":{}}],[\"submit_applications\",{\"_index\":75,\"name\":{\"92\":{}},\"comment\":{}}],[\"text\",{\"_index\":40,\"name\":{\"43\":{}},\"comment\":{}}],[\"token\",{\"_index\":43,\"name\":{\"46\":{}},\"comment\":{}}],[\"top\",{\"_index\":79,\"name\":{\"96\":{}},\"comment\":{}}],[\"ttl\",{\"_index\":45,\"name\":{\"48\":{}},\"comment\":{}}],[\"turkey\",{\"_index\":14,\"name\":{\"14\":{}},\"comment\":{}}],[\"type\",{\"_index\":44,\"name\":{\"47\":{}},\"comment\":{}}],[\"types\",{\"_index\":5,\"name\":{\"5\":{}},\"comment\":{}}],[\"ukr\",{\"_index\":8,\"name\":{\"8\":{}},\"comment\":{}}],[\"vk\",{\"_index\":86,\"name\":{\"116\":{}},\"comment\":{}}],[\"widgets/floatingonetap\",{\"_index\":3,\"name\":{\"3\":{}},\"comment\":{}}],[\"widgets/oauthlist\",{\"_index\":4,\"name\":{\"4\":{}},\"comment\":{}}],[\"widgets/onetap\",{\"_index\":2,\"name\":{\"2\":{}},\"comment\":{}}],[\"width\",{\"_index\":60,\"name\":{\"66\":{}},\"comment\":{}}]],\"pipeline\":[]}}"); \ No newline at end of file +window.searchData = JSON.parse("{\"rows\":[{\"kind\":2,\"name\":\"core/config\",\"url\":\"modules/core_config.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"auth\",\"url\":\"modules/auth.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"widgets/oneTap\",\"url\":\"modules/widgets_oneTap.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"widgets/floatingOneTap\",\"url\":\"modules/widgets_floatingOneTap.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"widgets/oauthList\",\"url\":\"modules/widgets_oauthList.html\",\"classes\":\"\"},{\"kind\":2,\"name\":\"types\",\"url\":\"modules/types.html\",\"classes\":\"\"},{\"kind\":8,\"name\":\"Languages\",\"url\":\"enums/types.Languages.html\",\"classes\":\"\",\"parent\":\"types\"},{\"kind\":16,\"name\":\"RUS\",\"url\":\"enums/types.Languages.html#RUS\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"UKR\",\"url\":\"enums/types.Languages.html#UKR\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"ENG\",\"url\":\"enums/types.Languages.html#ENG\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"SPA\",\"url\":\"enums/types.Languages.html#SPA\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"GERMAN\",\"url\":\"enums/types.Languages.html#GERMAN\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"POL\",\"url\":\"enums/types.Languages.html#POL\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"FRA\",\"url\":\"enums/types.Languages.html#FRA\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"UZB\",\"url\":\"enums/types.Languages.html#UZB\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"TURKEY\",\"url\":\"enums/types.Languages.html#TURKEY\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"KAZ\",\"url\":\"enums/types.Languages.html#KAZ\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":16,\"name\":\"BEL\",\"url\":\"enums/types.Languages.html#BEL\",\"classes\":\"\",\"parent\":\"types.Languages\"},{\"kind\":8,\"name\":\"Scheme\",\"url\":\"enums/types.Scheme.html\",\"classes\":\"\",\"parent\":\"types\"},{\"kind\":16,\"name\":\"LIGHT\",\"url\":\"enums/types.Scheme.html#LIGHT\",\"classes\":\"\",\"parent\":\"types.Scheme\"},{\"kind\":16,\"name\":\"DARK\",\"url\":\"enums/types.Scheme.html#DARK\",\"classes\":\"\",\"parent\":\"types.Scheme\"},{\"kind\":128,\"name\":\"Config\",\"url\":\"classes/core_config.Config.html\",\"classes\":\"\",\"parent\":\"core/config\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/core_config.Config.html#constructor\",\"classes\":\"\",\"parent\":\"core/config.Config\"},{\"kind\":2048,\"name\":\"init\",\"url\":\"classes/core_config.Config.html#init\",\"classes\":\"\",\"parent\":\"core/config.Config\"},{\"kind\":2048,\"name\":\"update\",\"url\":\"classes/core_config.Config.html#update\",\"classes\":\"\",\"parent\":\"core/config.Config\"},{\"kind\":2048,\"name\":\"get\",\"url\":\"classes/core_config.Config.html#get\",\"classes\":\"\",\"parent\":\"core/config.Config\"},{\"kind\":8,\"name\":\"ConfigAuthMode\",\"url\":\"enums/core_config.ConfigAuthMode.html\",\"classes\":\"\",\"parent\":\"core/config\"},{\"kind\":16,\"name\":\"Redirect\",\"url\":\"enums/core_config.ConfigAuthMode.html#Redirect\",\"classes\":\"\",\"parent\":\"core/config.ConfigAuthMode\"},{\"kind\":16,\"name\":\"InNewTab\",\"url\":\"enums/core_config.ConfigAuthMode.html#InNewTab\",\"classes\":\"\",\"parent\":\"core/config.ConfigAuthMode\"},{\"kind\":8,\"name\":\"Prompt\",\"url\":\"enums/core_config.Prompt.html\",\"classes\":\"\",\"parent\":\"core/config\"},{\"kind\":16,\"name\":\"Default\",\"url\":\"enums/core_config.Prompt.html#Default\",\"classes\":\"\",\"parent\":\"core/config.Prompt\"},{\"kind\":16,\"name\":\"None\",\"url\":\"enums/core_config.Prompt.html#None\",\"classes\":\"\",\"parent\":\"core/config.Prompt\"},{\"kind\":16,\"name\":\"Login\",\"url\":\"enums/core_config.Prompt.html#Login\",\"classes\":\"\",\"parent\":\"core/config.Prompt\"},{\"kind\":16,\"name\":\"Consent\",\"url\":\"enums/core_config.Prompt.html#Consent\",\"classes\":\"\",\"parent\":\"core/config.Prompt\"},{\"kind\":16,\"name\":\"SelectAccount\",\"url\":\"enums/core_config.Prompt.html#SelectAccount\",\"classes\":\"\",\"parent\":\"core/config.Prompt\"},{\"kind\":256,\"name\":\"ConfigData\",\"url\":\"interfaces/core_config.ConfigData.html\",\"classes\":\"\",\"parent\":\"core/config\"},{\"kind\":1024,\"name\":\"app\",\"url\":\"interfaces/core_config.ConfigData.html#app\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":1024,\"name\":\"redirectUrl\",\"url\":\"interfaces/core_config.ConfigData.html#redirectUrl\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":1024,\"name\":\"state\",\"url\":\"interfaces/core_config.ConfigData.html#state\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":1024,\"name\":\"codeVerifier\",\"url\":\"interfaces/core_config.ConfigData.html#codeVerifier\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":1024,\"name\":\"codeChallenge\",\"url\":\"interfaces/core_config.ConfigData.html#codeChallenge\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":1024,\"name\":\"scope\",\"url\":\"interfaces/core_config.ConfigData.html#scope\",\"classes\":\"\",\"parent\":\"core/config.ConfigData\"},{\"kind\":128,\"name\":\"Auth\",\"url\":\"classes/auth.Auth.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/auth.Auth.html#constructor\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":2048,\"name\":\"login\",\"url\":\"classes/auth.Auth.html#login\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":2048,\"name\":\"exchangeCode\",\"url\":\"classes/auth.Auth.html#exchangeCode\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":2048,\"name\":\"refreshToken\",\"url\":\"classes/auth.Auth.html#refreshToken\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":2048,\"name\":\"logout\",\"url\":\"classes/auth.Auth.html#logout\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":2048,\"name\":\"userInfo\",\"url\":\"classes/auth.Auth.html#userInfo\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":2048,\"name\":\"publicInfo\",\"url\":\"classes/auth.Auth.html#publicInfo\",\"classes\":\"\",\"parent\":\"auth.Auth\"},{\"kind\":8,\"name\":\"AuthErrorCode\",\"url\":\"enums/auth.AuthErrorCode.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":16,\"name\":\"EventNotSupported\",\"url\":\"enums/auth.AuthErrorCode.html#EventNotSupported\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":16,\"name\":\"CannotCreateNewTab\",\"url\":\"enums/auth.AuthErrorCode.html#CannotCreateNewTab\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":16,\"name\":\"NewTabHasBeenClosed\",\"url\":\"enums/auth.AuthErrorCode.html#NewTabHasBeenClosed\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":16,\"name\":\"AuthorizationFailed\",\"url\":\"enums/auth.AuthErrorCode.html#AuthorizationFailed\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":16,\"name\":\"StateMismatch\",\"url\":\"enums/auth.AuthErrorCode.html#StateMismatch\",\"classes\":\"\",\"parent\":\"auth.AuthErrorCode\"},{\"kind\":256,\"name\":\"AuthError\",\"url\":\"interfaces/auth.AuthError.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"error\",\"url\":\"interfaces/auth.AuthError.html#error\",\"classes\":\"\",\"parent\":\"auth.AuthError\"},{\"kind\":1024,\"name\":\"error_description\",\"url\":\"interfaces/auth.AuthError.html#error_description\",\"classes\":\"\",\"parent\":\"auth.AuthError\"},{\"kind\":1024,\"name\":\"error_uri\",\"url\":\"interfaces/auth.AuthError.html#error_uri\",\"classes\":\"\",\"parent\":\"auth.AuthError\"},{\"kind\":1024,\"name\":\"state\",\"url\":\"interfaces/auth.AuthError.html#state\",\"classes\":\"\",\"parent\":\"auth.AuthError\"},{\"kind\":1024,\"name\":\"code\",\"url\":\"interfaces/auth.AuthError.html#code\",\"classes\":\"\",\"parent\":\"auth.AuthError\"},{\"kind\":256,\"name\":\"AuthParams\",\"url\":\"interfaces/auth.AuthParams.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"scheme\",\"url\":\"interfaces/auth.AuthParams.html#scheme\",\"classes\":\"\",\"parent\":\"auth.AuthParams\"},{\"kind\":1024,\"name\":\"lang\",\"url\":\"interfaces/auth.AuthParams.html#lang\",\"classes\":\"\",\"parent\":\"auth.AuthParams\"},{\"kind\":256,\"name\":\"AuthResponse\",\"url\":\"interfaces/auth.AuthResponse.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"code\",\"url\":\"interfaces/auth.AuthResponse.html#code\",\"classes\":\"\",\"parent\":\"auth.AuthResponse\"},{\"kind\":1024,\"name\":\"type\",\"url\":\"interfaces/auth.AuthResponse.html#type\",\"classes\":\"\",\"parent\":\"auth.AuthResponse\"},{\"kind\":1024,\"name\":\"state\",\"url\":\"interfaces/auth.AuthResponse.html#state\",\"classes\":\"\",\"parent\":\"auth.AuthResponse\"},{\"kind\":1024,\"name\":\"device_id\",\"url\":\"interfaces/auth.AuthResponse.html#device_id\",\"classes\":\"\",\"parent\":\"auth.AuthResponse\"},{\"kind\":256,\"name\":\"LogoutResult\",\"url\":\"interfaces/auth.LogoutResult.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"response\",\"url\":\"interfaces/auth.LogoutResult.html#response\",\"classes\":\"\",\"parent\":\"auth.LogoutResult\"},{\"kind\":256,\"name\":\"PublicInfoResult\",\"url\":\"interfaces/auth.PublicInfoResult.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"user\",\"url\":\"interfaces/auth.PublicInfoResult.html#user\",\"classes\":\"\",\"parent\":\"auth.PublicInfoResult\"},{\"kind\":256,\"name\":\"TokenResult\",\"url\":\"interfaces/auth.TokenResult.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"access_token\",\"url\":\"interfaces/auth.TokenResult.html#access_token\",\"classes\":\"\",\"parent\":\"auth.TokenResult\"},{\"kind\":1024,\"name\":\"expires_in\",\"url\":\"interfaces/auth.TokenResult.html#expires_in\",\"classes\":\"\",\"parent\":\"auth.TokenResult\"},{\"kind\":1024,\"name\":\"id_token\",\"url\":\"interfaces/auth.TokenResult.html#id_token\",\"classes\":\"\",\"parent\":\"auth.TokenResult\"},{\"kind\":1024,\"name\":\"refresh_token\",\"url\":\"interfaces/auth.TokenResult.html#refresh_token\",\"classes\":\"\",\"parent\":\"auth.TokenResult\"},{\"kind\":1024,\"name\":\"state\",\"url\":\"interfaces/auth.TokenResult.html#state\",\"classes\":\"\",\"parent\":\"auth.TokenResult\"},{\"kind\":1024,\"name\":\"token_type\",\"url\":\"interfaces/auth.TokenResult.html#token_type\",\"classes\":\"\",\"parent\":\"auth.TokenResult\"},{\"kind\":1024,\"name\":\"user_id\",\"url\":\"interfaces/auth.TokenResult.html#user_id\",\"classes\":\"\",\"parent\":\"auth.TokenResult\"},{\"kind\":1024,\"name\":\"scope\",\"url\":\"interfaces/auth.TokenResult.html#scope\",\"classes\":\"\",\"parent\":\"auth.TokenResult\"},{\"kind\":256,\"name\":\"UserInfoResult\",\"url\":\"interfaces/auth.UserInfoResult.html\",\"classes\":\"\",\"parent\":\"auth\"},{\"kind\":1024,\"name\":\"user\",\"url\":\"interfaces/auth.UserInfoResult.html#user\",\"classes\":\"\",\"parent\":\"auth.UserInfoResult\"},{\"kind\":128,\"name\":\"OneTap\",\"url\":\"classes/widgets_oneTap.OneTap.html\",\"classes\":\"\",\"parent\":\"widgets/oneTap\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/widgets_oneTap.OneTap.html#constructor\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"render\",\"url\":\"classes/widgets_oneTap.OneTap.html#render\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"close\",\"url\":\"classes/widgets_oneTap.OneTap.html#close\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"show\",\"url\":\"classes/widgets_oneTap.OneTap.html#show\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"hide\",\"url\":\"classes/widgets_oneTap.OneTap.html#hide\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"on\",\"url\":\"classes/widgets_oneTap.OneTap.html#on\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":2048,\"name\":\"off\",\"url\":\"classes/widgets_oneTap.OneTap.html#off\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTap\"},{\"kind\":256,\"name\":\"OneTapParams\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html\",\"classes\":\"\",\"parent\":\"widgets/oneTap\"},{\"kind\":1024,\"name\":\"showAlternativeLogin\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#showAlternativeLogin\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"styles\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#styles\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"skin\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#skin\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"oauthList\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#oauthList\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"container\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#container\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"scheme\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#scheme\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":1024,\"name\":\"lang\",\"url\":\"interfaces/widgets_oneTap.OneTapParams.html#lang\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oneTap.OneTapParams\"},{\"kind\":256,\"name\":\"OneTapStyles\",\"url\":\"interfaces/widgets_oneTap.OneTapStyles.html\",\"classes\":\"\",\"parent\":\"widgets/oneTap\"},{\"kind\":1024,\"name\":\"width\",\"url\":\"interfaces/widgets_oneTap.OneTapStyles.html#width\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapStyles\"},{\"kind\":1024,\"name\":\"height\",\"url\":\"interfaces/widgets_oneTap.OneTapStyles.html#height\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapStyles\"},{\"kind\":1024,\"name\":\"borderRadius\",\"url\":\"interfaces/widgets_oneTap.OneTapStyles.html#borderRadius\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapStyles\"},{\"kind\":8,\"name\":\"OneTapSkin\",\"url\":\"enums/widgets_oneTap.OneTapSkin.html\",\"classes\":\"\",\"parent\":\"widgets/oneTap\"},{\"kind\":16,\"name\":\"Primary\",\"url\":\"enums/widgets_oneTap.OneTapSkin.html#Primary\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapSkin\"},{\"kind\":16,\"name\":\"Secondary\",\"url\":\"enums/widgets_oneTap.OneTapSkin.html#Secondary\",\"classes\":\"\",\"parent\":\"widgets/oneTap.OneTapSkin\"},{\"kind\":128,\"name\":\"FloatingOneTap\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#constructor\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"render\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#render\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"close\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#close\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"show\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#show\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"hide\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#hide\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"on\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#on\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":2048,\"name\":\"off\",\"url\":\"classes/widgets_floatingOneTap.FloatingOneTap.html#off\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTap\"},{\"kind\":256,\"name\":\"FloatingOneTapParams\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap\"},{\"kind\":1024,\"name\":\"indent\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#indent\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"contentId\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#contentId\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"showAlternativeLogin\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#showAlternativeLogin\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"appName\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#appName\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"oauthList\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#oauthList\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"scheme\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#scheme\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":1024,\"name\":\"lang\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapParams.html#lang\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapParams\"},{\"kind\":8,\"name\":\"FloatingOneTapContentId\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap\"},{\"kind\":16,\"name\":\"SIGN_IN_TO_SERVICE\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#SIGN_IN_TO_SERVICE\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"SIGN_IN_TO_ACCOUNT\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#SIGN_IN_TO_ACCOUNT\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"REGISTRATION_FOR_EVENT\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#REGISTRATION_FOR_EVENT\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"SUBMIT_APPLICATIONS\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#SUBMIT_APPLICATIONS\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"MAKE_ORDER_WITH_SERVICE\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#MAKE_ORDER_WITH_SERVICE\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":16,\"name\":\"MAKE_ORDER_WITHOUT_SERVICE\",\"url\":\"enums/widgets_floatingOneTap.FloatingOneTapContentId.html#MAKE_ORDER_WITHOUT_SERVICE\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapContentId\"},{\"kind\":256,\"name\":\"FloatingOneTapIndent\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap\"},{\"kind\":1024,\"name\":\"top\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html#top\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapIndent\"},{\"kind\":1024,\"name\":\"right\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html#right\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapIndent\"},{\"kind\":1024,\"name\":\"bottom\",\"url\":\"interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html#bottom\",\"classes\":\"\",\"parent\":\"widgets/floatingOneTap.FloatingOneTapIndent\"},{\"kind\":128,\"name\":\"OAuthList\",\"url\":\"classes/widgets_oauthList.OAuthList.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/widgets_oauthList.OAuthList.html#constructor\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"render\",\"url\":\"classes/widgets_oauthList.OAuthList.html#render\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"close\",\"url\":\"classes/widgets_oauthList.OAuthList.html#close\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"show\",\"url\":\"classes/widgets_oauthList.OAuthList.html#show\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"hide\",\"url\":\"classes/widgets_oauthList.OAuthList.html#hide\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"on\",\"url\":\"classes/widgets_oauthList.OAuthList.html#on\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":2048,\"name\":\"off\",\"url\":\"classes/widgets_oauthList.OAuthList.html#off\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthList\"},{\"kind\":256,\"name\":\"OAuthListParams\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":1024,\"name\":\"styles\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#styles\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":1024,\"name\":\"oauthList\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#oauthList\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":1024,\"name\":\"container\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#container\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":1024,\"name\":\"scheme\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#scheme\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":1024,\"name\":\"lang\",\"url\":\"interfaces/widgets_oauthList.OAuthListParams.html#lang\",\"classes\":\"tsd-is-inherited\",\"parent\":\"widgets/oauthList.OAuthListParams\"},{\"kind\":8,\"name\":\"OAuthName\",\"url\":\"enums/widgets_oauthList.OAuthName.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":16,\"name\":\"OK\",\"url\":\"enums/widgets_oauthList.OAuthName.html#OK\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthName\"},{\"kind\":16,\"name\":\"MAIL\",\"url\":\"enums/widgets_oauthList.OAuthName.html#MAIL\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthName\"},{\"kind\":16,\"name\":\"VK\",\"url\":\"enums/widgets_oauthList.OAuthName.html#VK\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthName\"},{\"kind\":8,\"name\":\"ExternalOAuthName\",\"url\":\"enums/widgets_oauthList.ExternalOAuthName.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":16,\"name\":\"OK\",\"url\":\"enums/widgets_oauthList.ExternalOAuthName.html#OK\",\"classes\":\"\",\"parent\":\"widgets/oauthList.ExternalOAuthName\"},{\"kind\":16,\"name\":\"MAIL\",\"url\":\"enums/widgets_oauthList.ExternalOAuthName.html#MAIL\",\"classes\":\"\",\"parent\":\"widgets/oauthList.ExternalOAuthName\"},{\"kind\":256,\"name\":\"OAuthListStyles\",\"url\":\"interfaces/widgets_oauthList.OAuthListStyles.html\",\"classes\":\"\",\"parent\":\"widgets/oauthList\"},{\"kind\":1024,\"name\":\"height\",\"url\":\"interfaces/widgets_oauthList.OAuthListStyles.html#height\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthListStyles\"},{\"kind\":1024,\"name\":\"borderRadius\",\"url\":\"interfaces/widgets_oauthList.OAuthListStyles.html#borderRadius\",\"classes\":\"\",\"parent\":\"widgets/oauthList.OAuthListStyles\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"comment\"],\"fieldVectors\":[[\"name/0\",[0,46.697]],[\"comment/0\",[]],[\"name/1\",[1,41.589]],[\"comment/1\",[]],[\"name/2\",[2,46.697]],[\"comment/2\",[]],[\"name/3\",[3,46.697]],[\"comment/3\",[]],[\"name/4\",[4,46.697]],[\"comment/4\",[]],[\"name/5\",[5,46.697]],[\"comment/5\",[]],[\"name/6\",[6,46.697]],[\"comment/6\",[]],[\"name/7\",[7,46.697]],[\"comment/7\",[]],[\"name/8\",[8,46.697]],[\"comment/8\",[]],[\"name/9\",[9,46.697]],[\"comment/9\",[]],[\"name/10\",[10,46.697]],[\"comment/10\",[]],[\"name/11\",[11,46.697]],[\"comment/11\",[]],[\"name/12\",[12,46.697]],[\"comment/12\",[]],[\"name/13\",[13,46.697]],[\"comment/13\",[]],[\"name/14\",[14,46.697]],[\"comment/14\",[]],[\"name/15\",[15,46.697]],[\"comment/15\",[]],[\"name/16\",[16,46.697]],[\"comment/16\",[]],[\"name/17\",[17,46.697]],[\"comment/17\",[]],[\"name/18\",[18,33.704]],[\"comment/18\",[]],[\"name/19\",[19,46.697]],[\"comment/19\",[]],[\"name/20\",[20,46.697]],[\"comment/20\",[]],[\"name/21\",[21,46.697]],[\"comment/21\",[]],[\"name/22\",[22,33.704]],[\"comment/22\",[]],[\"name/23\",[23,46.697]],[\"comment/23\",[]],[\"name/24\",[24,46.697]],[\"comment/24\",[]],[\"name/25\",[25,46.697]],[\"comment/25\",[]],[\"name/26\",[26,46.697]],[\"comment/26\",[]],[\"name/27\",[27,46.697]],[\"comment/27\",[]],[\"name/28\",[28,46.697]],[\"comment/28\",[]],[\"name/29\",[29,46.697]],[\"comment/29\",[]],[\"name/30\",[30,46.697]],[\"comment/30\",[]],[\"name/31\",[31,46.697]],[\"comment/31\",[]],[\"name/32\",[32,41.589]],[\"comment/32\",[]],[\"name/33\",[33,46.697]],[\"comment/33\",[]],[\"name/34\",[34,46.697]],[\"comment/34\",[]],[\"name/35\",[35,46.697]],[\"comment/35\",[]],[\"name/36\",[36,46.697]],[\"comment/36\",[]],[\"name/37\",[37,46.697]],[\"comment/37\",[]],[\"name/38\",[38,35.711]],[\"comment/38\",[]],[\"name/39\",[39,46.697]],[\"comment/39\",[]],[\"name/40\",[40,46.697]],[\"comment/40\",[]],[\"name/41\",[41,41.589]],[\"comment/41\",[]],[\"name/42\",[1,41.589]],[\"comment/42\",[]],[\"name/43\",[22,33.704]],[\"comment/43\",[]],[\"name/44\",[32,41.589]],[\"comment/44\",[]],[\"name/45\",[42,46.697]],[\"comment/45\",[]],[\"name/46\",[43,46.697]],[\"comment/46\",[]],[\"name/47\",[44,46.697]],[\"comment/47\",[]],[\"name/48\",[45,46.697]],[\"comment/48\",[]],[\"name/49\",[46,46.697]],[\"comment/49\",[]],[\"name/50\",[47,46.697]],[\"comment/50\",[]],[\"name/51\",[48,46.697]],[\"comment/51\",[]],[\"name/52\",[49,46.697]],[\"comment/52\",[]],[\"name/53\",[50,46.697]],[\"comment/53\",[]],[\"name/54\",[51,46.697]],[\"comment/54\",[]],[\"name/55\",[52,46.697]],[\"comment/55\",[]],[\"name/56\",[53,46.697]],[\"comment/56\",[]],[\"name/57\",[54,46.697]],[\"comment/57\",[]],[\"name/58\",[55,46.697]],[\"comment/58\",[]],[\"name/59\",[56,46.697]],[\"comment/59\",[]],[\"name/60\",[38,35.711]],[\"comment/60\",[]],[\"name/61\",[57,41.589]],[\"comment/61\",[]],[\"name/62\",[58,46.697]],[\"comment/62\",[]],[\"name/63\",[18,33.704]],[\"comment/63\",[]],[\"name/64\",[59,35.711]],[\"comment/64\",[]],[\"name/65\",[60,46.697]],[\"comment/65\",[]],[\"name/66\",[57,41.589]],[\"comment/66\",[]],[\"name/67\",[61,46.697]],[\"comment/67\",[]],[\"name/68\",[38,35.711]],[\"comment/68\",[]],[\"name/69\",[62,46.697]],[\"comment/69\",[]],[\"name/70\",[63,46.697]],[\"comment/70\",[]],[\"name/71\",[64,46.697]],[\"comment/71\",[]],[\"name/72\",[65,46.697]],[\"comment/72\",[]],[\"name/73\",[66,41.589]],[\"comment/73\",[]],[\"name/74\",[67,46.697]],[\"comment/74\",[]],[\"name/75\",[68,46.697]],[\"comment/75\",[]],[\"name/76\",[69,46.697]],[\"comment/76\",[]],[\"name/77\",[70,46.697]],[\"comment/77\",[]],[\"name/78\",[71,46.697]],[\"comment/78\",[]],[\"name/79\",[38,35.711]],[\"comment/79\",[]],[\"name/80\",[72,46.697]],[\"comment/80\",[]],[\"name/81\",[73,46.697]],[\"comment/81\",[]],[\"name/82\",[41,41.589]],[\"comment/82\",[]],[\"name/83\",[74,46.697]],[\"comment/83\",[]],[\"name/84\",[66,41.589]],[\"comment/84\",[]],[\"name/85\",[75,46.697]],[\"comment/85\",[]],[\"name/86\",[22,33.704]],[\"comment/86\",[]],[\"name/87\",[76,38.224]],[\"comment/87\",[]],[\"name/88\",[77,38.224]],[\"comment/88\",[]],[\"name/89\",[78,38.224]],[\"comment/89\",[]],[\"name/90\",[79,38.224]],[\"comment/90\",[]],[\"name/91\",[80,38.224]],[\"comment/91\",[]],[\"name/92\",[81,38.224]],[\"comment/92\",[]],[\"name/93\",[82,46.697]],[\"comment/93\",[]],[\"name/94\",[83,41.589]],[\"comment/94\",[]],[\"name/95\",[84,41.589]],[\"comment/95\",[]],[\"name/96\",[85,46.697]],[\"comment/96\",[]],[\"name/97\",[86,35.711]],[\"comment/97\",[]],[\"name/98\",[87,41.589]],[\"comment/98\",[]],[\"name/99\",[18,33.704]],[\"comment/99\",[]],[\"name/100\",[59,35.711]],[\"comment/100\",[]],[\"name/101\",[88,46.697]],[\"comment/101\",[]],[\"name/102\",[89,46.697]],[\"comment/102\",[]],[\"name/103\",[90,41.589]],[\"comment/103\",[]],[\"name/104\",[91,41.589]],[\"comment/104\",[]],[\"name/105\",[92,46.697]],[\"comment/105\",[]],[\"name/106\",[93,46.697]],[\"comment/106\",[]],[\"name/107\",[94,46.697]],[\"comment/107\",[]],[\"name/108\",[95,46.697]],[\"comment/108\",[]],[\"name/109\",[22,33.704]],[\"comment/109\",[]],[\"name/110\",[76,38.224]],[\"comment/110\",[]],[\"name/111\",[77,38.224]],[\"comment/111\",[]],[\"name/112\",[78,38.224]],[\"comment/112\",[]],[\"name/113\",[79,38.224]],[\"comment/113\",[]],[\"name/114\",[80,38.224]],[\"comment/114\",[]],[\"name/115\",[81,38.224]],[\"comment/115\",[]],[\"name/116\",[96,46.697]],[\"comment/116\",[]],[\"name/117\",[97,46.697]],[\"comment/117\",[]],[\"name/118\",[98,46.697]],[\"comment/118\",[]],[\"name/119\",[83,41.589]],[\"comment/119\",[]],[\"name/120\",[99,46.697]],[\"comment/120\",[]],[\"name/121\",[86,35.711]],[\"comment/121\",[]],[\"name/122\",[18,33.704]],[\"comment/122\",[]],[\"name/123\",[59,35.711]],[\"comment/123\",[]],[\"name/124\",[100,46.697]],[\"comment/124\",[]],[\"name/125\",[101,46.697]],[\"comment/125\",[]],[\"name/126\",[102,46.697]],[\"comment/126\",[]],[\"name/127\",[103,46.697]],[\"comment/127\",[]],[\"name/128\",[104,46.697]],[\"comment/128\",[]],[\"name/129\",[105,46.697]],[\"comment/129\",[]],[\"name/130\",[106,46.697]],[\"comment/130\",[]],[\"name/131\",[107,46.697]],[\"comment/131\",[]],[\"name/132\",[108,46.697]],[\"comment/132\",[]],[\"name/133\",[109,46.697]],[\"comment/133\",[]],[\"name/134\",[110,46.697]],[\"comment/134\",[]],[\"name/135\",[86,35.711]],[\"comment/135\",[]],[\"name/136\",[22,33.704]],[\"comment/136\",[]],[\"name/137\",[76,38.224]],[\"comment/137\",[]],[\"name/138\",[77,38.224]],[\"comment/138\",[]],[\"name/139\",[78,38.224]],[\"comment/139\",[]],[\"name/140\",[79,38.224]],[\"comment/140\",[]],[\"name/141\",[80,38.224]],[\"comment/141\",[]],[\"name/142\",[81,38.224]],[\"comment/142\",[]],[\"name/143\",[111,46.697]],[\"comment/143\",[]],[\"name/144\",[84,41.589]],[\"comment/144\",[]],[\"name/145\",[86,35.711]],[\"comment/145\",[]],[\"name/146\",[87,41.589]],[\"comment/146\",[]],[\"name/147\",[18,33.704]],[\"comment/147\",[]],[\"name/148\",[59,35.711]],[\"comment/148\",[]],[\"name/149\",[112,46.697]],[\"comment/149\",[]],[\"name/150\",[113,41.589]],[\"comment/150\",[]],[\"name/151\",[114,41.589]],[\"comment/151\",[]],[\"name/152\",[115,46.697]],[\"comment/152\",[]],[\"name/153\",[116,46.697]],[\"comment/153\",[]],[\"name/154\",[113,41.589]],[\"comment/154\",[]],[\"name/155\",[114,41.589]],[\"comment/155\",[]],[\"name/156\",[117,46.697]],[\"comment/156\",[]],[\"name/157\",[90,41.589]],[\"comment/157\",[]],[\"name/158\",[91,41.589]],[\"comment/158\",[]]],\"invertedIndex\":[[\"access_token\",{\"_index\":68,\"name\":{\"75\":{}},\"comment\":{}}],[\"app\",{\"_index\":36,\"name\":{\"36\":{}},\"comment\":{}}],[\"appname\",{\"_index\":99,\"name\":{\"120\":{}},\"comment\":{}}],[\"auth\",{\"_index\":1,\"name\":{\"1\":{},\"42\":{}},\"comment\":{}}],[\"autherror\",{\"_index\":53,\"name\":{\"56\":{}},\"comment\":{}}],[\"autherrorcode\",{\"_index\":47,\"name\":{\"50\":{}},\"comment\":{}}],[\"authorizationfailed\",{\"_index\":51,\"name\":{\"54\":{}},\"comment\":{}}],[\"authparams\",{\"_index\":58,\"name\":{\"62\":{}},\"comment\":{}}],[\"authresponse\",{\"_index\":60,\"name\":{\"65\":{}},\"comment\":{}}],[\"bel\",{\"_index\":17,\"name\":{\"17\":{}},\"comment\":{}}],[\"borderradius\",{\"_index\":91,\"name\":{\"104\":{},\"158\":{}},\"comment\":{}}],[\"bottom\",{\"_index\":110,\"name\":{\"134\":{}},\"comment\":{}}],[\"cannotcreatenewtab\",{\"_index\":49,\"name\":{\"52\":{}},\"comment\":{}}],[\"close\",{\"_index\":77,\"name\":{\"88\":{},\"111\":{},\"138\":{}},\"comment\":{}}],[\"code\",{\"_index\":57,\"name\":{\"61\":{},\"66\":{}},\"comment\":{}}],[\"codechallenge\",{\"_index\":40,\"name\":{\"40\":{}},\"comment\":{}}],[\"codeverifier\",{\"_index\":39,\"name\":{\"39\":{}},\"comment\":{}}],[\"config\",{\"_index\":21,\"name\":{\"21\":{}},\"comment\":{}}],[\"configauthmode\",{\"_index\":26,\"name\":{\"26\":{}},\"comment\":{}}],[\"configdata\",{\"_index\":35,\"name\":{\"35\":{}},\"comment\":{}}],[\"consent\",{\"_index\":33,\"name\":{\"33\":{}},\"comment\":{}}],[\"constructor\",{\"_index\":22,\"name\":{\"22\":{},\"43\":{},\"86\":{},\"109\":{},\"136\":{}},\"comment\":{}}],[\"container\",{\"_index\":87,\"name\":{\"98\":{},\"146\":{}},\"comment\":{}}],[\"contentid\",{\"_index\":98,\"name\":{\"118\":{}},\"comment\":{}}],[\"core/config\",{\"_index\":0,\"name\":{\"0\":{}},\"comment\":{}}],[\"dark\",{\"_index\":20,\"name\":{\"20\":{}},\"comment\":{}}],[\"default\",{\"_index\":30,\"name\":{\"30\":{}},\"comment\":{}}],[\"device_id\",{\"_index\":62,\"name\":{\"69\":{}},\"comment\":{}}],[\"eng\",{\"_index\":9,\"name\":{\"9\":{}},\"comment\":{}}],[\"error\",{\"_index\":54,\"name\":{\"57\":{}},\"comment\":{}}],[\"error_description\",{\"_index\":55,\"name\":{\"58\":{}},\"comment\":{}}],[\"error_uri\",{\"_index\":56,\"name\":{\"59\":{}},\"comment\":{}}],[\"eventnotsupported\",{\"_index\":48,\"name\":{\"51\":{}},\"comment\":{}}],[\"exchangecode\",{\"_index\":42,\"name\":{\"45\":{}},\"comment\":{}}],[\"expires_in\",{\"_index\":69,\"name\":{\"76\":{}},\"comment\":{}}],[\"externaloauthname\",{\"_index\":116,\"name\":{\"153\":{}},\"comment\":{}}],[\"floatingonetap\",{\"_index\":95,\"name\":{\"108\":{}},\"comment\":{}}],[\"floatingonetapcontentid\",{\"_index\":100,\"name\":{\"124\":{}},\"comment\":{}}],[\"floatingonetapindent\",{\"_index\":107,\"name\":{\"131\":{}},\"comment\":{}}],[\"floatingonetapparams\",{\"_index\":96,\"name\":{\"116\":{}},\"comment\":{}}],[\"fra\",{\"_index\":13,\"name\":{\"13\":{}},\"comment\":{}}],[\"german\",{\"_index\":11,\"name\":{\"11\":{}},\"comment\":{}}],[\"get\",{\"_index\":25,\"name\":{\"25\":{}},\"comment\":{}}],[\"height\",{\"_index\":90,\"name\":{\"103\":{},\"157\":{}},\"comment\":{}}],[\"hide\",{\"_index\":79,\"name\":{\"90\":{},\"113\":{},\"140\":{}},\"comment\":{}}],[\"id_token\",{\"_index\":70,\"name\":{\"77\":{}},\"comment\":{}}],[\"indent\",{\"_index\":97,\"name\":{\"117\":{}},\"comment\":{}}],[\"init\",{\"_index\":23,\"name\":{\"23\":{}},\"comment\":{}}],[\"innewtab\",{\"_index\":28,\"name\":{\"28\":{}},\"comment\":{}}],[\"kaz\",{\"_index\":16,\"name\":{\"16\":{}},\"comment\":{}}],[\"lang\",{\"_index\":59,\"name\":{\"64\":{},\"100\":{},\"123\":{},\"148\":{}},\"comment\":{}}],[\"languages\",{\"_index\":6,\"name\":{\"6\":{}},\"comment\":{}}],[\"light\",{\"_index\":19,\"name\":{\"19\":{}},\"comment\":{}}],[\"login\",{\"_index\":32,\"name\":{\"32\":{},\"44\":{}},\"comment\":{}}],[\"logout\",{\"_index\":44,\"name\":{\"47\":{}},\"comment\":{}}],[\"logoutresult\",{\"_index\":63,\"name\":{\"70\":{}},\"comment\":{}}],[\"mail\",{\"_index\":114,\"name\":{\"151\":{},\"155\":{}},\"comment\":{}}],[\"make_order_with_service\",{\"_index\":105,\"name\":{\"129\":{}},\"comment\":{}}],[\"make_order_without_service\",{\"_index\":106,\"name\":{\"130\":{}},\"comment\":{}}],[\"newtabhasbeenclosed\",{\"_index\":50,\"name\":{\"53\":{}},\"comment\":{}}],[\"none\",{\"_index\":31,\"name\":{\"31\":{}},\"comment\":{}}],[\"oauthlist\",{\"_index\":86,\"name\":{\"97\":{},\"121\":{},\"135\":{},\"145\":{}},\"comment\":{}}],[\"oauthlistparams\",{\"_index\":111,\"name\":{\"143\":{}},\"comment\":{}}],[\"oauthliststyles\",{\"_index\":117,\"name\":{\"156\":{}},\"comment\":{}}],[\"oauthname\",{\"_index\":112,\"name\":{\"149\":{}},\"comment\":{}}],[\"off\",{\"_index\":81,\"name\":{\"92\":{},\"115\":{},\"142\":{}},\"comment\":{}}],[\"ok\",{\"_index\":113,\"name\":{\"150\":{},\"154\":{}},\"comment\":{}}],[\"on\",{\"_index\":80,\"name\":{\"91\":{},\"114\":{},\"141\":{}},\"comment\":{}}],[\"onetap\",{\"_index\":75,\"name\":{\"85\":{}},\"comment\":{}}],[\"onetapparams\",{\"_index\":82,\"name\":{\"93\":{}},\"comment\":{}}],[\"onetapskin\",{\"_index\":92,\"name\":{\"105\":{}},\"comment\":{}}],[\"onetapstyles\",{\"_index\":88,\"name\":{\"101\":{}},\"comment\":{}}],[\"pol\",{\"_index\":12,\"name\":{\"12\":{}},\"comment\":{}}],[\"primary\",{\"_index\":93,\"name\":{\"106\":{}},\"comment\":{}}],[\"prompt\",{\"_index\":29,\"name\":{\"29\":{}},\"comment\":{}}],[\"publicinfo\",{\"_index\":46,\"name\":{\"49\":{}},\"comment\":{}}],[\"publicinforesult\",{\"_index\":65,\"name\":{\"72\":{}},\"comment\":{}}],[\"redirect\",{\"_index\":27,\"name\":{\"27\":{}},\"comment\":{}}],[\"redirecturl\",{\"_index\":37,\"name\":{\"37\":{}},\"comment\":{}}],[\"refresh_token\",{\"_index\":71,\"name\":{\"78\":{}},\"comment\":{}}],[\"refreshtoken\",{\"_index\":43,\"name\":{\"46\":{}},\"comment\":{}}],[\"registration_for_event\",{\"_index\":103,\"name\":{\"127\":{}},\"comment\":{}}],[\"render\",{\"_index\":76,\"name\":{\"87\":{},\"110\":{},\"137\":{}},\"comment\":{}}],[\"response\",{\"_index\":64,\"name\":{\"71\":{}},\"comment\":{}}],[\"right\",{\"_index\":109,\"name\":{\"133\":{}},\"comment\":{}}],[\"rus\",{\"_index\":7,\"name\":{\"7\":{}},\"comment\":{}}],[\"scheme\",{\"_index\":18,\"name\":{\"18\":{},\"63\":{},\"99\":{},\"122\":{},\"147\":{}},\"comment\":{}}],[\"scope\",{\"_index\":41,\"name\":{\"41\":{},\"82\":{}},\"comment\":{}}],[\"secondary\",{\"_index\":94,\"name\":{\"107\":{}},\"comment\":{}}],[\"selectaccount\",{\"_index\":34,\"name\":{\"34\":{}},\"comment\":{}}],[\"show\",{\"_index\":78,\"name\":{\"89\":{},\"112\":{},\"139\":{}},\"comment\":{}}],[\"showalternativelogin\",{\"_index\":83,\"name\":{\"94\":{},\"119\":{}},\"comment\":{}}],[\"sign_in_to_account\",{\"_index\":102,\"name\":{\"126\":{}},\"comment\":{}}],[\"sign_in_to_service\",{\"_index\":101,\"name\":{\"125\":{}},\"comment\":{}}],[\"skin\",{\"_index\":85,\"name\":{\"96\":{}},\"comment\":{}}],[\"spa\",{\"_index\":10,\"name\":{\"10\":{}},\"comment\":{}}],[\"state\",{\"_index\":38,\"name\":{\"38\":{},\"60\":{},\"68\":{},\"79\":{}},\"comment\":{}}],[\"statemismatch\",{\"_index\":52,\"name\":{\"55\":{}},\"comment\":{}}],[\"styles\",{\"_index\":84,\"name\":{\"95\":{},\"144\":{}},\"comment\":{}}],[\"submit_applications\",{\"_index\":104,\"name\":{\"128\":{}},\"comment\":{}}],[\"token_type\",{\"_index\":72,\"name\":{\"80\":{}},\"comment\":{}}],[\"tokenresult\",{\"_index\":67,\"name\":{\"74\":{}},\"comment\":{}}],[\"top\",{\"_index\":108,\"name\":{\"132\":{}},\"comment\":{}}],[\"turkey\",{\"_index\":15,\"name\":{\"15\":{}},\"comment\":{}}],[\"type\",{\"_index\":61,\"name\":{\"67\":{}},\"comment\":{}}],[\"types\",{\"_index\":5,\"name\":{\"5\":{}},\"comment\":{}}],[\"ukr\",{\"_index\":8,\"name\":{\"8\":{}},\"comment\":{}}],[\"update\",{\"_index\":24,\"name\":{\"24\":{}},\"comment\":{}}],[\"user\",{\"_index\":66,\"name\":{\"73\":{},\"84\":{}},\"comment\":{}}],[\"user_id\",{\"_index\":73,\"name\":{\"81\":{}},\"comment\":{}}],[\"userinfo\",{\"_index\":45,\"name\":{\"48\":{}},\"comment\":{}}],[\"userinforesult\",{\"_index\":74,\"name\":{\"83\":{}},\"comment\":{}}],[\"uzb\",{\"_index\":14,\"name\":{\"14\":{}},\"comment\":{}}],[\"vk\",{\"_index\":115,\"name\":{\"152\":{}},\"comment\":{}}],[\"widgets/floatingonetap\",{\"_index\":3,\"name\":{\"3\":{}},\"comment\":{}}],[\"widgets/oauthlist\",{\"_index\":4,\"name\":{\"4\":{}},\"comment\":{}}],[\"widgets/onetap\",{\"_index\":2,\"name\":{\"2\":{}},\"comment\":{}}],[\"width\",{\"_index\":89,\"name\":{\"102\":{}},\"comment\":{}}]],\"pipeline\":[]}}"); \ No newline at end of file diff --git a/docs/classes/auth.Auth.html b/docs/classes/auth.Auth.html index 5c2e584..4900788 100644 --- a/docs/classes/auth.Auth.html +++ b/docs/classes/auth.Auth.html @@ -1,4 +1,4 @@ -Auth | @vkid/sdk - v1.1.0
+Auth | @vkid/sdk - v2.0.0-alpha
  • Preparing search index...
  • -
  • The search index is not available
@vkid/sdk - v1.1.0
+
  • The search index is not available
  • @vkid/sdk - v2.0.0-alpha
    @@ -31,7 +31,12 @@

    Constructors

    Methods

    -

    Constructors

    @@ -43,17 +48,76 @@

    Methods

    +
    + +
      + +
    • +
      +

      Parameters

      +
        +
      • +
        code: string
      • +
      • +
        deviceId: string
      +

      Returns Promise<Omit<TokenResult, "id_token">>

      - +
    • Parameters

      -

      Returns void

    +

    Returns Promise<void>

    +
    + +
    +
    + +
    +
    + +
      + +
    • +
      +

      Parameters

      +
        +
      • +
        refreshToken: string
      • +
      • +
        deviceId: string
      +

      Returns Promise<TokenResult>

    +
    + +
    +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -110,6 +184,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/classes/core_config.Config.html b/docs/classes/core_config.Config.html index 37fce53..985d4b5 100644 --- a/docs/classes/core_config.Config.html +++ b/docs/classes/core_config.Config.html @@ -1,4 +1,4 @@ -Config | @vkid/sdk - v1.1.0
      +Config | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha

  • @@ -32,7 +32,8 @@

    Constructors

    Methods

    Constructors

    @@ -50,10 +51,21 @@
    -
    - +
    +
      - + +
    • +
      +

      Parameters

      +
        +
      • +
        config: Object
      +

      Returns Config

    +
    + +
      +
    • Parameters

      @@ -80,9 +92,10 @@

      constructor

    • get
    • -
    • set
    +
  • init
  • +
  • update
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -118,6 +136,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/classes/widgets_floatingOneTap.FloatingOneTap.html b/docs/classes/widgets_floatingOneTap.FloatingOneTap.html index fb83323..f3a9704 100644 --- a/docs/classes/widgets_floatingOneTap.FloatingOneTap.html +++ b/docs/classes/widgets_floatingOneTap.FloatingOneTap.html @@ -1,4 +1,4 @@ -FloatingOneTap | @vkid/sdk - v1.1.0
      +FloatingOneTap | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -29,7 +29,7 @@

    Constructors

    -
    +
    -
    +

    Overrides Widget<Omit<FloatingOneTapParams, 'appName'>>.constructor

  • Methods

    @@ -129,7 +129,7 @@

    Theme

    @@ -6,7 +6,7 @@
    • Preparing search index...
    • -
    • The search index is not available
    @vkid/sdk - v1.1.0 +
  • The search index is not available
  • @vkid/sdk - v2.0.0-alpha
    @@ -29,7 +29,7 @@

    Constructors

    -
    +
    -
      +
      • Returns OAuthList

    +

    Overrides Widget<OAuthListParams>.constructor

    Methods

    @@ -129,7 +129,7 @@

    Theme

    @@ -6,7 +6,7 @@
    • Preparing search index...
    • -
    • The search index is not available
    @vkid/sdk - v1.1.0 +
  • The search index is not available
  • @vkid/sdk - v2.0.0-alpha
    @@ -29,7 +29,7 @@

    Constructors

    -
    +
    -
      +
      • Returns OneTap

    +

    Overrides Widget<OneTapParams>.constructor

    Methods

    @@ -129,7 +129,7 @@

    Theme

    @@ -6,7 +6,7 @@
    • Preparing search index...
    • -
    • The search index is not available
    @vkid/sdk - v1.1.0 +
  • The search index is not available
  • @vkid/sdk - v2.0.0-alpha

    Enumeration Members

    @@ -49,6 +50,11 @@
    NewTabHasBeenClosed: 102

    Новая вкладка была закрыта

    +
    +
    + +
    StateMismatch: 104
    +

    Проверка стейта завершилась с ошибкой

    +
  • NewTabHasBeenClosed
  • +
  • StateMismatch
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -108,6 +120,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/enums/core_config.ConfigAuthMode.html b/docs/enums/core_config.ConfigAuthMode.html index 73d067e..c60c6df 100644 --- a/docs/enums/core_config.ConfigAuthMode.html +++ b/docs/enums/core_config.ConfigAuthMode.html @@ -1,4 +1,4 @@ -ConfigAuthMode | @vkid/sdk - v1.1.0
      +ConfigAuthMode | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -54,7 +54,7 @@

    InNewTab

  • Redirect
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -90,6 +95,7 @@

    widgets/oauthList
    @vkid/sdk - v2.0.0-alpha
    @@ -23,19 +23,25 @@

    Enumeration Members

    +
    + +
    BEL: 114
    - +
    ENG: 3
    @@ -43,6 +49,9 @@
    GERMAN: 6
    +
    + +
    KAZ: 97
    POL: 15
    @@ -57,7 +66,10 @@
    -
    UKR: 1
    +
    UKR: 1
    +
    + +
    UZB: 65
    • Preparing search index...
    • -
    • The search index is not available
    @vkid/sdk - v1.1.0
    +
  • The search index is not available
  • @vkid/sdk - v2.0.0-alpha
    @@ -54,7 +54,7 @@

    DARK

  • LIGHT
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -90,6 +95,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/enums/widgets_floatingOneTap.FloatingOneTapContentId.html b/docs/enums/widgets_floatingOneTap.FloatingOneTapContentId.html index ef9202f..12ca150 100644 --- a/docs/enums/widgets_floatingOneTap.FloatingOneTapContentId.html +++ b/docs/enums/widgets_floatingOneTap.FloatingOneTapContentId.html @@ -1,4 +1,4 @@ -FloatingOneTapContentId | @vkid/sdk - v1.1.0
      +FloatingOneTapContentId | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -86,7 +86,7 @@

    SIGN_IN_TO_SERVICE

  • SUBMIT_APPLICATIONS
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -122,6 +127,7 @@

    widgets/oauthList
    @vkid/sdk - v2.0.0-alpha
    @@ -59,7 +59,7 @@

    OK

  • VK
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -95,6 +100,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/enums/widgets_oneTap.OneTapSkin.html b/docs/enums/widgets_oneTap.OneTapSkin.html index 98a4cd3..9dfcd1d 100644 --- a/docs/enums/widgets_oneTap.OneTapSkin.html +++ b/docs/enums/widgets_oneTap.OneTapSkin.html @@ -1,4 +1,4 @@ -OneTapSkin | @vkid/sdk - v1.1.0
      +OneTapSkin | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -54,7 +54,7 @@

    Primary

  • Secondary
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -90,6 +95,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/index.html b/docs/index.html index 8781b1b..7042a12 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,4 +1,4 @@ -@vkid/sdk - v1.1.0
      +@vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    -

    @vkid/sdk - v1.1.0

    +

    @vkid/sdk - v2.0.0-alpha

    @@ -38,6 +38,8 @@

    +
    +

    ℹ️ Версия VK ID SDK 2.0.0-alpha поддерживает авторизацию по протоколу OAuth 2.1, а также способы входа через аккаунты Одноклассников и Mail.ru. Если вы хотите участвовать в тестировании этой версии SDK или узнать о ней подробнее, напишите нам на почту devsupport@corp.vk.com.


    VK ID SDK сейчас находится в бета-тестировании. О проблемах вы можете сообщить с помощью issues репозитория.


    @@ -51,7 +53,7 @@

    pnpm add @vkid/sdk
     

    CDN:

    -
    <script src="https://unpkg.com/@vkid/sdk@latest/dist-sdk/umd/index.js"></script>
    +
    <script src="https://unpkg.com/@vkid/sdk@2.0.0-alpha/dist-sdk/umd/index.js"></script>
     

    Обратите внимание: Для работы авторизации нужен APP_ID. Вы получите его, когда создадите приложение в кабинете подключения VK ID.

    @@ -59,21 +61,21 @@

    Пример

    Базовая авторизация -
    import * as VKID from '@vkid/sdk';

    VKID.Config.set({
    app: APP_ID,
    redirectUrl: 'https://example.com'
    });


    const authButton = document.createElement('button');
    authButton.onclick = () => {
    VKID.Auth.login(); // После авторизации будет редирект на адрес, указанный в параметре redirect_uri
    };

    document.getElementById('container').appendChild(authButton); +
    import * as VKID from '@vkid/sdk';

    VKID.Config.init({
    app: APP_ID,
    redirectUrl: 'https://example.com',
    state: 'state',
    codeVerifier: 'codeVerifier',
    scope: 'phone email',
    });


    const authButton = document.createElement('button');
    authButton.onclick = () => {
    // После авторизации будет редирект на адрес, указанный в параметре redirectUrl
    VKID.Auth.login()
    .catch(console.error);
    };

    document.getElementById('container').appendChild(authButton);
    OneTap -
    import * as VKID from '@vkid/sdk';

    VKID.Config.set({
    app: APP_ID,
    redirectUrl: 'https://example.com'
    });

    const oneTap = new VKID.OneTap();

    const container = document.getElementById('VkIdSdkOneTap');

    if (container) {
    oneTap.render({ container });
    } +
    import * as VKID from '@vkid/sdk';

    VKID.Config.init({
    app: APP_ID,
    redirectUrl: 'https://example.com',
    state: 'state',
    codeVerifier: 'codeVerifier',
    scope: 'phone email',
    });

    const oneTap = new VKID.OneTap();

    const container = document.getElementById('VkIdSdkOneTap');

    if (container) {
    oneTap
    .render({ container })
    .on(VKID.WidgetEvents.ERROR, console.error);
    }

    Документация

    Contributing

    Проект VK ID SDK имеет открытый исходный код на GitHub, и вы можете присоединиться к его доработке — мы будем благодарны за внесение улучшений и исправление возможных ошибок.

    @@ -111,7 +113,7 @@

    Code of Conduct

  • Contributing Guide
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -147,6 +154,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/auth.AuthError.html b/docs/interfaces/auth.AuthError.html index 55d1418..69f438b 100644 --- a/docs/interfaces/auth.AuthError.html +++ b/docs/interfaces/auth.AuthError.html @@ -1,4 +1,4 @@ -AuthError | @vkid/sdk - v1.1.0
      +AuthError | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -27,26 +27,38 @@

    Properties

    - - -

    Код ошибки

    + + +

    Код ошибки, возникшей во время работы SDK

    -
    - -
    details?: any
    +
    + +
    error: string
    +

    Текст ошибки

    +
    +
    + +
    error_description?: string

    Расширенная информация об ошибке

    -
    - -
    text: string
    -

    Текст ошибки

    +
    + +
    error_uri?: string
    +

    Страница HTML с человеко-понятным описанием ошибки.

    +
    +
    + +
    state?: string
    +

    Строка переданная в изначальном запросе.

    +
  • error
  • +
  • error_description
  • +
  • error_uri
  • +
  • state
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -105,6 +124,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/auth.AuthParams.html b/docs/interfaces/auth.AuthParams.html index 9868529..b0cb02e 100644 --- a/docs/interfaces/auth.AuthParams.html +++ b/docs/interfaces/auth.AuthParams.html @@ -1,4 +1,4 @@ -AuthParams | @vkid/sdk - v1.1.0
      +AuthParams | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -62,7 +62,7 @@

    lang

  • scheme
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -98,6 +103,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/auth.AuthResponse.html b/docs/interfaces/auth.AuthResponse.html index f39e9a2..2470fa0 100644 --- a/docs/interfaces/auth.AuthResponse.html +++ b/docs/interfaces/auth.AuthResponse.html @@ -1,4 +1,4 @@ -AuthResponse | @vkid/sdk - v1.1.0
      +AuthResponse | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -27,25 +27,31 @@

    Properties

    -
    - -
    token: string
    -

    Токен, полученный после прохождения авторизации

    +
    + +
    code: string
    +

    Код, полученный после прохождения авторизации

    -
    - -
    ttl: number
    -

    Время жизни токена

    +
    + +
    device_id: string
    +

    Идентификатор устройства, использовавшийся для создания кода

    +
    +
    + +
    state: string
    +

    Состояние, указанное в конфиге

    -
    type: "silent_token"
    +
    type: "code_v2"

    Вид токена

    @@ -65,11 +71,12 @@

    Theme

    +
    +
    +
      +
    • Preparing search index...
    • +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    +
    +
    +
    +
    + +

    Interface LogoutResult

    +
    +

    Hierarchy

    +
      +
    • LogoutResult
    +
    +
    +
    + +
    +
    +

    Properties

    +
    +
    +

    Properties

    +
    + +
    response: number
    +
    +
    +

    Generated using TypeDoc

    +
    \ No newline at end of file diff --git a/docs/interfaces/auth.PublicInfoResult.html b/docs/interfaces/auth.PublicInfoResult.html new file mode 100644 index 0000000..c4ba741 --- /dev/null +++ b/docs/interfaces/auth.PublicInfoResult.html @@ -0,0 +1,112 @@ +PublicInfoResult | @vkid/sdk - v2.0.0-alpha
    +
    + +
    +
    +
    +
    + +

    Interface PublicInfoResult

    +
    +

    Hierarchy

    +
      +
    • PublicInfoResult
    +
    +
    +
    + +
    +
    +

    Properties

    +
    +
    +

    Properties

    +
    + +
    user: UserData
    +
    +
    +

    Generated using TypeDoc

    +
    \ No newline at end of file diff --git a/docs/interfaces/auth.TokenResult.html b/docs/interfaces/auth.TokenResult.html new file mode 100644 index 0000000..544b3d6 --- /dev/null +++ b/docs/interfaces/auth.TokenResult.html @@ -0,0 +1,147 @@ +TokenResult | @vkid/sdk - v2.0.0-alpha
    +
    + +
    +
    +
    +
    + +

    Interface TokenResult

    +
    +

    Hierarchy

    +
      +
    • TokenResult
    +
    +
    +
    + +
    +
    +

    Properties

    +
    + +
    access_token: string
    +
    + +
    expires_in: number
    +
    + +
    id_token: string
    +
    + +
    refresh_token: string
    +
    + +
    scope: string
    +
    + +
    state: string
    +
    + +
    token_type: string
    +
    + +
    user_id: number
    +
    +
    +

    Generated using TypeDoc

    +
    \ No newline at end of file diff --git a/docs/interfaces/auth.UserInfoResult.html b/docs/interfaces/auth.UserInfoResult.html new file mode 100644 index 0000000..97bb3f2 --- /dev/null +++ b/docs/interfaces/auth.UserInfoResult.html @@ -0,0 +1,112 @@ +UserInfoResult | @vkid/sdk - v2.0.0-alpha
    +
    + +
    +
    +
    +
    + +

    Interface UserInfoResult

    +
    +

    Hierarchy

    +
      +
    • UserInfoResult
    +
    +
    +
    + +
    +
    +

    Properties

    +
    +
    +

    Properties

    +
    + +
    user: Partial<UserData>
    +
    +
    +

    Generated using TypeDoc

    +
    \ No newline at end of file diff --git a/docs/interfaces/core_config.ConfigData.html b/docs/interfaces/core_config.ConfigData.html index c4b1ed9..faef121 100644 --- a/docs/interfaces/core_config.ConfigData.html +++ b/docs/interfaces/core_config.ConfigData.html @@ -1,4 +1,4 @@ -ConfigData | @vkid/sdk - v1.1.0
    +ConfigData | @vkid/sdk - v2.0.0-alpha
    • Preparing search index...
    • -
    • The search index is not available
    @vkid/sdk - v1.1.0
    +
  • The search index is not available
  • @vkid/sdk - v2.0.0-alpha
    @@ -28,8 +28,10 @@

    Properties

    @@ -37,12 +39,18 @@

    Properties

    app: number
    -
    - -
    +
    + +
    codeChallenge?: string
    +
    + +
    codeVerifier?: string
    redirectUrl: string
    +
    + +
    scope?: string
    state?: string
    @@ -64,11 +72,13 @@

  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -104,6 +119,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html b/docs/interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html index 06a0334..ea4958a 100644 --- a/docs/interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html +++ b/docs/interfaces/widgets_floatingOneTap.FloatingOneTapIndent.html @@ -1,4 +1,4 @@ -FloatingOneTapIndent | @vkid/sdk - v1.1.0
      +FloatingOneTapIndent | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -69,7 +69,7 @@

    right

  • top
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -105,6 +110,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/widgets_floatingOneTap.FloatingOneTapParams.html b/docs/interfaces/widgets_floatingOneTap.FloatingOneTapParams.html index 3d26883..4b52b10 100644 --- a/docs/interfaces/widgets_floatingOneTap.FloatingOneTapParams.html +++ b/docs/interfaces/widgets_floatingOneTap.FloatingOneTapParams.html @@ -1,4 +1,4 @@ -FloatingOneTapParams | @vkid/sdk - v1.1.0
      +FloatingOneTapParams | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -101,7 +101,7 @@

    scheme

  • showAlternativeLogin
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -137,6 +142,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/widgets_oauthList.OAuthListParams.html b/docs/interfaces/widgets_oauthList.OAuthListParams.html index b63a079..a8b150d 100644 --- a/docs/interfaces/widgets_oauthList.OAuthListParams.html +++ b/docs/interfaces/widgets_oauthList.OAuthListParams.html @@ -1,4 +1,4 @@ -OAuthListParams | @vkid/sdk - v1.1.0
      +OAuthListParams | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -88,7 +88,7 @@

    scheme

  • styles
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -124,6 +129,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/widgets_oauthList.OAuthListStyles.html b/docs/interfaces/widgets_oauthList.OAuthListStyles.html index a8f0439..dbb3d85 100644 --- a/docs/interfaces/widgets_oauthList.OAuthListStyles.html +++ b/docs/interfaces/widgets_oauthList.OAuthListStyles.html @@ -1,4 +1,4 @@ -OAuthListStyles | @vkid/sdk - v1.1.0
      +OAuthListStyles | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -62,7 +62,7 @@

    borderRadius

  • height
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -98,6 +103,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/widgets_oneTap.OneTapParams.html b/docs/interfaces/widgets_oneTap.OneTapParams.html index 6b04702..edd6a2e 100644 --- a/docs/interfaces/widgets_oneTap.OneTapParams.html +++ b/docs/interfaces/widgets_oneTap.OneTapParams.html @@ -1,4 +1,4 @@ -OneTapParams | @vkid/sdk - v1.1.0
      +OneTapParams | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -102,7 +102,7 @@

    skin

  • styles
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -138,6 +143,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/interfaces/widgets_oneTap.OneTapStyles.html b/docs/interfaces/widgets_oneTap.OneTapStyles.html index 9975a3e..86165ad 100644 --- a/docs/interfaces/widgets_oneTap.OneTapStyles.html +++ b/docs/interfaces/widgets_oneTap.OneTapStyles.html @@ -1,4 +1,4 @@ -OneTapStyles | @vkid/sdk - v1.1.0
      +OneTapStyles | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -69,7 +69,7 @@

    height

  • width
  • +
  • AuthResponse
  • +
  • LogoutResult
  • +
  • PublicInfoResult
  • +
  • TokenResult
  • +
  • UserInfoResult
  • core/config
  • @@ -105,6 +110,7 @@

    widgets/oauthList
      +
    • ExternalOAuthName
    • OAuthName
    • OAuthList
    • OAuthListParams
    • diff --git a/docs/modules/auth.html b/docs/modules/auth.html index bd20a10..2bd5f81 100644 --- a/docs/modules/auth.html +++ b/docs/modules/auth.html @@ -1,4 +1,4 @@ -auth | @vkid/sdk - v1.1.0
      +auth | @vkid/sdk - v2.0.0-alpha
      • Preparing search index...
      • -
      • The search index is not available
      @vkid/sdk - v1.1.0
      +
    • The search index is not available
    @vkid/sdk - v2.0.0-alpha
    @@ -21,6 +21,7 @@

    Index

    Enumerations

    Classes

    @@ -44,7 +45,7 @@

    Member Visibility

    Theme

    @@ -37,7 +37,7 @@

    Member Visibility

    Theme

    @@ -45,7 +45,7 @@

    Member Visibility

    Theme

    @@ -20,7 +20,8 @@

    Module widgets/oauthList

    Index

    Enumerations

    -

    Classes

    @@ -45,7 +46,7 @@

    Member Visibility

    Theme

    @@ -45,7 +45,7 @@

    Member Visibility

    Theme