-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[PerUserAuth] Add EARS auth type for Connectors V2 #253695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
159 commits
Select commit
Hold shift + click to select a range
d5913de
[WorkplaceAI] Add authz code-grant flow in Stack Connectors V2 (#246655)
seanstory 01cf3be
[ResponseOps][Connectors] Add auth mode to auth types (#252307)
jcger c989b64
Merge branch 'main' of https://github.com/jcger/kibana into connector…
jcger 6ae9569
[Workplace AI][PerUserAuth] Support connectors created in non default…
lorenabalan 52cc7e8
[Workplace AI][PerUserAuth] Escape callback html and oauth state clie…
lorenabalan b8f0483
Merge branch 'main' into connectors-auth-code-grant
jcger 2865111
[ResponseOps][Connectors] Add authMode to connector saved objects and…
js-jankisalvi f1e5cf2
[WorkplaceAI][PerUserAuth] Remove `redirectUri` from `oauth_state` SO…
lorenabalan a63cbfd
Merge branch 'main' into connectors-auth-code-grant
jcger fe99023
[WorkplaceAI][PerUserAuth] Add unit tests for OAuth Code Grant Flow (…
lorenabalan bfa8e7f
[ResponseOps][Connectors] Add authentication column to connectors tab…
js-jankisalvi 7bc6b62
[Response Ops][Connectors] Add new user token SO (#252501)
jcger 83c0328
Init commit
lorenabalan da1e500
Merge branch 'main' into connectors-auth-code-grant
dennis-tismenko 846c86b
Add missing unit tests
lorenabalan 6776339
Refactor common code and update unit tests
lorenabalan 8041b7d
Get auth type from secrets
lorenabalan f393e79
Enable EARS auth on Google connector
lorenabalan c3ce4da
Enable Authorize button in the UI
lorenabalan 49b890e
Bug fixes
lorenabalan df98a36
Merge branch 'main' into connectors-auth-code-grant
jcger 6a19640
Fix OAuth State cleanup task
lorenabalan 5b38f89
Set EARS base URL from config
lorenabalan 5b7af60
Only specify provider in connector input
lorenabalan 67c523c
Fix refresh logic
lorenabalan 83491d4
Merge and fix conflicts
lorenabalan 625d85a
Lint
lorenabalan b2412b2
Pass actual id to refresh flow as well
lorenabalan b5f4bf4
[WorkplaceAI][PerUserAuth] Add hooks for connector code grant OAuth f…
dennis-tismenko 1b86769
Merge branch 'main' into connectors-auth-code-grant
dennis-tismenko b403663
Changes from node scripts/generate codeowners
kibanamachine f004982
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine 25a6409
Merge branch 'main' of github.com:jcger/kibana into connectors-auth-c…
jcger c942aef
Small fixes (#254557)
lorenabalan a4b08c0
fix SO count test + docs
jcger 460ebf7
Merge branch 'connectors-auth-code-grant' of github.com:elastic/kiban…
jcger e8bcea2
Changes from make api-docs
kibanamachine e7e0dd0
add xpack.actions.auth.oauth_authorization_code.enabled flag
jcger 2fd16c9
Changes from make api-docs
kibanamachine a47ef6d
FF effect on SO and authMode in GET connectors
jcger 1207799
Merge branch 'connectors-auth-code-grant' of github.com:elastic/kiban…
jcger 82a2597
[ResponseOps][Connectors] Use profileUid in actions client (#254589)
jcger 92b7bb4
Merge branch 'main' into connectors-auth-code-grant
jcger 3a192f0
fix tests
jcger 354bd23
Merge branch 'connectors-auth-code-grant' of github.com:elastic/kiban…
jcger a386360
Merge branch 'main' of github.com:jcger/kibana into connectors-auth-c…
jcger abff0b5
reset core + docs
jcger ff13481
Changes from make api-docs
kibanamachine bf90b46
[ResponseOps][PerUserAuth] Delete user tokens on connector delete and…
js-jankisalvi ac6e2da
Changes from node scripts/jest_integration -u src/core/server/integra…
kibanamachine b1c1a81
Merge and fix conflicts, best effort
lorenabalan f2269a5
Post-merge fixes
lorenabalan 0f3eb62
conditional schema models
jcger bc79bda
Merge branch 'main' into connectors-auth-code-grant
jcger e3bb9cd
[WorkplaceAI][PerUserAuth] Implement Encrypted Saved Objects recommen…
lorenabalan 3bca053
Merge branch 'connectors-auth-code-grant' into lb/poc/ears-auth
lorenabalan 78e721d
remove feature flag
jcger 8d27c46
Changes from node scripts/check_mappings_update --fix
kibanamachine b40260b
Changes from make api-docs
kibanamachine bf8164d
update SO counter
jcger a8174bf
Merge branch 'lb/poc/ears-auth' of github.com:elastic/kibana into pr-…
jcger c13e3f9
set xpack.workplaceAIApp.ears.url flag
jcger b6d2faa
Changes from node scripts/jest_integration -u src/core/server/integra…
kibanamachine 9b5b5f1
Fix; check for user tokens instead of shared ones
lorenabalan 2c7d0e4
Merge branch 'lb/poc/ears-auth' of github.com:elastic/kibana into lb/…
lorenabalan 2fe0512
fix tests
jcger fd873d4
remove kbn setting
jcger 0eab256
trigger deployment, empty commit
lorenabalan e15fdb6
Merge branch 'lb/poc/ears-auth' of github.com:elastic/kibana into lb/…
lorenabalan ada770b
Merge branch 'main' into connectors-auth-code-grant
jcger a16ff65
Merge branch 'connectors-auth-code-grant' of github.com:elastic/kiban…
jcger 6359806
wire wpai for label deploy
jcger 4f3cd55
update SO count
jcger 4cb6dff
EARS url in actions config
lorenabalan dd77ebe
Merge branch 'lb/poc/ears-auth' of github.com:elastic/kibana into lb/…
lorenabalan 253a362
fix test
jcger fe98754
Merge branch 'main' of github.com:jcger/kibana into connectors-auth-c…
jcger 638bef0
Merge branch 'main' into connectors-auth-code-grant
jcger dcde963
[ResponseOps][Connectors] Authorization Code - Remove feature flag (…
jcger 9818ab6
Merge branch 'main' into connectors-auth-code-grant
jcger d7d1bfa
rollback limits + fix test
jcger 02e131e
Merge branch 'connectors-auth-code-grant' of github.com:elastic/kiban…
jcger 15d2c19
rename auth rate limit kbn setting to
jcger 8999b5c
add missing fixture
jcger fe05a44
Merge branch 'main' into connectors-auth-code-grant
jcger 3e36591
Undo CI pipeline changes for workplace_ai
lorenabalan 66df421
Use discriminated union
lorenabalan 44e1d47
removed unrelated code
jcger 8081451
Reset lock mapping
lorenabalan d1c8066
Remove noisy type
lorenabalan a3ac3ae
fix test
jcger 0b23084
Merge branch 'connectors-auth-code-grant' of github.com:elastic/kiban…
jcger 3b58a2b
Merge branch 'connectors-auth-code-grant' into lb/poc/ears-auth
lorenabalan e72d8c3
Factor out duplicate code
lorenabalan 1a59817
Isolate ears-related code
lorenabalan ce098bf
Refactor switches into one Strategy object
lorenabalan 62c16cb
add missing authMode
jcger d136c1a
Merge branch 'main' into connectors-auth-code-grant
jcger 6ae2892
Merge branch 'main' of github.com:jcger/kibana into connectors-auth-c…
jcger 1425dce
Fix tests
lorenabalan d0cf87b
Refactor resolveEarsUrl
lorenabalan cc836cb
Merge branch 'connectors-auth-code-grant' into lb/poc/ears-auth
lorenabalan 5d57743
Fix bad merge
lorenabalan 55dffe2
Simplify ears url config handling
lorenabalan 08fbe1a
Fix bad merge again
lorenabalan 3eb6448
Clean up how we derive endpoints
lorenabalan e767818
Fix tests and remove discriminated union
lorenabalan 34cfe1b
More minor cleaning up
lorenabalan 7582df0
Fix authz endpoints
lorenabalan 34708e5
fix refresh token
jcger 97288d3
Merge branch 'main' of github.com:jcger/kibana into connectors-auth-c…
jcger 84cce1b
Merge branch 'main' into connectors-auth-code-grant
jcger 343bf64
Merge branch 'main' into connectors-auth-code-grant
jcger 22f6f7b
update moon files
jcger 184a1b4
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine b95ddbb
Merge branch 'main' of github.com:jcger/kibana into connectors-auth-c…
jcger 2d7309d
Merge branch 'connectors-auth-code-grant' into lb/poc/ears-auth
lorenabalan 6030c89
solve conflicts
jcger 354c11c
Merge branch 'main' of github.com:jcger/kibana into connectors-auth-c…
jcger 3f46049
remove logs
jcger 81d9c25
add test and reenable basic auth for client_secret_basic
jcger 3324000
Merge branch 'main' into connectors-auth-code-grant
jcger 798f72d
DRY providers and URL schema type
lorenabalan f8597ab
Merge branch 'main' into connectors-auth-code-grant
jcger a919e0b
Debug log and update docstring
lorenabalan 5a560dd
Merge branch 'connectors-auth-code-grant' into lb/poc/ears-auth
lorenabalan dbb5ade
Update codeowners
lorenabalan a0ed2ea
Add README
lorenabalan 7833754
Update imports
lorenabalan 9a9e7a6
Update with EARS API version
lorenabalan 0eeb9dd
Raise more generic error message
lorenabalan 643e6e5
Fix tests
lorenabalan c98fc91
Fix bad merge
lorenabalan 7cffe7c
Remove unused label
lorenabalan 22e77aa
Add guard for connectorTokenClient
lorenabalan e509539
Put back discriminated union
lorenabalan 89beff8
Remove leftover capitalize
lorenabalan f102ca7
Merge branch 'main' into lb/poc/ears-auth
lorenabalan 3b960b4
Merge branch 'main' into lb/poc/ears-auth
lorenabalan f2408ee
Update readme with api version
lorenabalan 09f6ae7
Update axiosInstance headers for future requests
lorenabalan b395e81
Fix useBasicAuth propagation
lorenabalan ea58466
Reset Google Drive connector
lorenabalan bd3da1a
Fix tests
lorenabalan 268368a
Merge branch 'main' into lb/poc/ears-auth
lorenabalan 5f8cfee
Update codeowners
lorenabalan a0102c8
Merge branch 'main' into lb/poc/ears-auth
lorenabalan 957c16b
Merge branch 'main' into lb/poc/ears-auth
lorenabalan 8640bdd
Key lock by connector ID and profile UID (#257968)
lorenabalan ef7cc7f
Merge branch 'main' into lb/poc/ears-auth
lorenabalan eae5bb4
Merge branch 'main' into lb/poc/ears-auth
lorenabalan e993ff9
Hmm fix validateOAuthConnector IDE complaint for now
lorenabalan c88f2e4
Fix - delete lock by lockKey; cover with unit tests
lorenabalan f3d24c3
Update label for consistency
lorenabalan 32a8536
Check config too for authType
lorenabalan 331e3a7
Remove dead code
lorenabalan c1c1dee
Check both secrets and config
lorenabalan 318d461
Remove dead code from FE too
lorenabalan 052d580
Merge branch 'main' into lb/poc/ears-auth
lorenabalan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
src/platform/packages/shared/kbn-connector-specs/src/auth_types/ears.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| import { z } from '@kbn/zod/v4'; | ||
| import type { AxiosInstance } from 'axios'; | ||
| import type { AuthContext, AuthTypeSpec } from '../connector_spec'; | ||
| import * as i18n from './translations'; | ||
|
|
||
| export const EARS_PROVIDERS = ['google', 'microsoft', 'slack'] as const; | ||
|
|
||
| const authSchema = z | ||
| .object({ | ||
| provider: z.enum(EARS_PROVIDERS).meta({ hidden: true }), | ||
| scope: z.string().meta({ label: i18n.OAUTH_SCOPE_LABEL }).optional(), | ||
| }) | ||
| .meta({ label: i18n.EARS_LABEL }); | ||
|
|
||
| type AuthSchemaType = z.infer<typeof authSchema>; | ||
|
|
||
| /** | ||
| * EARS (Elastic Authentication Redirect Service) OAuth Flow | ||
| * | ||
| * EARS is an OAuth proxy that manages client credentials (clientId/clientSecret) | ||
| * on behalf of the user. Instead of users creating their own OAuth apps for each | ||
| * 3rd party, they can rely on the Elastic-owned apps for simplicity. | ||
| * Therefore, connectors using EARS don't require users to input any | ||
| * client credentials — EARS already knows them. | ||
| * | ||
| * EARS Redirect Flow: | ||
| * 1. On `/_start_oauth_flow`, Kibana builds EARS authorize URL with callback_uri, state, scope, pkce_challenge, pkce_method, and redirects to it | ||
| * 2. User visits EARS authorize URL → EARS redirects to OAuth provider and shows auth screen to user, in order for them to enter their credentials and authorize scopes | ||
| * 3. OAuth provider redirects back to EARS with authz code & state | ||
| * 4. EARS redirects to callback_uri (Kibana's `/_oauth_callback`) with authz code & state | ||
| * 5. Kibana then exchanges code via EARS token endpoint: POST {earsTokenUrl} with code & pkce_verifier in the JSON body | ||
| * 6. Tokens are auto-refreshed when expired during connector execution | ||
| */ | ||
| export const Ears: AuthTypeSpec<AuthSchemaType> = { | ||
| id: 'ears', | ||
| schema: authSchema, | ||
| authMode: 'per-user', | ||
| configure: async ( | ||
| ctx: AuthContext, | ||
| axiosInstance: AxiosInstance, | ||
| secret: AuthSchemaType | ||
| ): Promise<AxiosInstance> => { | ||
| let token; | ||
| try { | ||
| token = await ctx.getToken({ | ||
| authType: 'ears', | ||
| provider: secret.provider, | ||
| scope: secret.scope, | ||
| }); | ||
| } catch (error) { | ||
| throw new Error( | ||
| `Unable to retrieve/refresh the access token. User may need to re-authorize: ${error.message}` | ||
| ); | ||
| } | ||
|
|
||
| if (!token) { | ||
| throw new Error(`No access token available. User must complete OAuth authorization flow.`); | ||
| } | ||
|
|
||
| // set global defaults | ||
| axiosInstance.defaults.headers.common.Authorization = token; | ||
|
|
||
| return axiosInstance; | ||
| }, | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
...platform/plugins/shared/actions/server/lib/axios_auth_strategies/default_strategy.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| jest.mock('../get_oauth_client_credentials_access_token'); | ||
| jest.mock('../delete_token_axios_interceptor'); | ||
|
|
||
| import type { AxiosInstance } from 'axios'; | ||
| import type { GetTokenOpts, OAuthGetTokenOpts } from '@kbn/connector-specs'; | ||
| import { loggerMock } from '@kbn/logging-mocks'; | ||
| import { actionsConfigMock } from '../../actions_config.mock'; | ||
| import { connectorTokenClientMock } from '../connector_token_client.mock'; | ||
| import { getOAuthClientCredentialsAccessToken } from '../get_oauth_client_credentials_access_token'; | ||
| import { getDeleteTokenAxiosInterceptor } from '../delete_token_axios_interceptor'; | ||
| import { DefaultStrategy } from './default_strategy'; | ||
| import type { AuthStrategyDeps } from './types'; | ||
|
|
||
| const mockGetOAuthClientCredentialsAccessToken = | ||
| getOAuthClientCredentialsAccessToken as jest.MockedFunction< | ||
| typeof getOAuthClientCredentialsAccessToken | ||
| >; | ||
| const mockGetDeleteTokenAxiosInterceptor = getDeleteTokenAxiosInterceptor as jest.MockedFunction< | ||
| typeof getDeleteTokenAxiosInterceptor | ||
| >; | ||
|
|
||
| const logger = loggerMock.create(); | ||
| const configurationUtilities = actionsConfigMock.create(); | ||
| const connectorTokenClient = connectorTokenClientMock.create(); | ||
|
|
||
| const baseDeps: AuthStrategyDeps = { | ||
| connectorId: 'connector-1', | ||
| secrets: { | ||
| clientId: 'my-client-id', | ||
| clientSecret: 'my-client-secret', | ||
| tokenUrl: 'https://provider.example.com/token', | ||
| scope: 'openid', | ||
| }, | ||
| connectorTokenClient, | ||
| logger, | ||
| configurationUtilities, | ||
| }; | ||
|
|
||
| const createMockAxiosInstance = () => | ||
| ({ | ||
| interceptors: { response: { use: jest.fn() } }, | ||
| } as unknown as AxiosInstance); | ||
|
|
||
| describe('DefaultStrategy', () => { | ||
| let strategy: DefaultStrategy; | ||
|
|
||
| const mockOnFulfilled = jest.fn(); | ||
| const mockOnRejected = jest.fn(); | ||
|
|
||
| beforeEach(() => { | ||
| jest.clearAllMocks(); | ||
| strategy = new DefaultStrategy(); | ||
| mockGetDeleteTokenAxiosInterceptor.mockReturnValue({ | ||
| onFulfilled: mockOnFulfilled, | ||
| onRejected: mockOnRejected, | ||
| }); | ||
| }); | ||
|
|
||
| describe('installResponseInterceptor', () => { | ||
| it('installs the delete-token cleanup interceptor', () => { | ||
| const instance = createMockAxiosInstance(); | ||
| strategy.installResponseInterceptor(instance, baseDeps); | ||
|
|
||
| expect(mockGetDeleteTokenAxiosInterceptor).toHaveBeenCalledWith({ | ||
| connectorTokenClient, | ||
| connectorId: 'connector-1', | ||
| }); | ||
| expect(instance.interceptors.response.use).toHaveBeenCalledWith( | ||
| mockOnFulfilled, | ||
| mockOnRejected | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| describe('getToken', () => { | ||
| it('throws when opts authType is not oauth', async () => { | ||
| const opts: GetTokenOpts = { authType: 'ears', provider: 'google' }; | ||
| await expect(strategy.getToken(opts, baseDeps)).rejects.toThrow( | ||
| 'DefaultStrategy received non-oauth token opts' | ||
| ); | ||
| }); | ||
|
|
||
| it('delegates to getOAuthClientCredentialsAccessToken with correct args', async () => { | ||
| mockGetOAuthClientCredentialsAccessToken.mockResolvedValue('Bearer clientcred'); | ||
|
|
||
| const opts: OAuthGetTokenOpts = { | ||
| authType: 'oauth', | ||
| tokenUrl: 'https://provider.example.com/token', | ||
| clientId: 'the-client-id', | ||
| clientSecret: 'the-client-secret', | ||
| scope: 'openid profile', | ||
| }; | ||
| const result = await strategy.getToken(opts, baseDeps); | ||
|
|
||
| expect(result).toBe('Bearer clientcred'); | ||
| expect(mockGetOAuthClientCredentialsAccessToken).toHaveBeenCalledWith( | ||
| expect.objectContaining({ | ||
| connectorId: 'connector-1', | ||
| tokenUrl: 'https://provider.example.com/token', | ||
| oAuthScope: 'openid profile', | ||
| credentials: { | ||
| config: { clientId: 'the-client-id' }, | ||
| secrets: { clientSecret: 'the-client-secret' }, | ||
| }, | ||
| connectorTokenClient, | ||
| }) | ||
| ); | ||
| }); | ||
|
|
||
| it('includes additionalFields when present in opts', async () => { | ||
| mockGetOAuthClientCredentialsAccessToken.mockResolvedValue('Bearer token'); | ||
|
|
||
| const opts: OAuthGetTokenOpts = { | ||
| authType: 'oauth', | ||
| tokenUrl: 'https://provider.example.com/token', | ||
| clientId: 'id', | ||
| clientSecret: 'secret', | ||
| additionalFields: { tenant: 'abc' }, | ||
| }; | ||
| await strategy.getToken(opts, baseDeps); | ||
|
|
||
| expect(mockGetOAuthClientCredentialsAccessToken).toHaveBeenCalledWith( | ||
| expect.objectContaining({ | ||
| credentials: expect.objectContaining({ | ||
| config: expect.objectContaining({ additionalFields: { tenant: 'abc' } }), | ||
| }), | ||
| }) | ||
| ); | ||
| }); | ||
| }); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.