Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,19 @@ describe('signInWithRedirect', () => {
expect(mockUrlSafeEncode).toHaveBeenCalledWith(expectedCustomState);
});

it('uses extra query parameters when specified', async () => {
const expectedDefaultProvider = 'COGNITO';
const exptedParamKey = 'customParam';
const expectedParamValue = 'object';
await signInWithRedirect({
extraQueryParams: { customParam: expectedParamValue },
});
const [oauthUrl] = mockOpenAuthSession.mock.calls[0];
expect(oauthUrl).toStrictEqual(
`https://oauth.domain.com/oauth2/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A3000%2F&response_type=code&client_id=userPoolClientId&identity_provider=${expectedDefaultProvider}&scope=phone%20email%20openid%20profile%20aws.cognito.signin.user.admin&state=oauth_state&code_challenge=code_challenge&code_challenge_method=S256&${exptedParamKey}=${expectedParamValue}`,
);
});

describe('specifications on Web', () => {
describe('side effect', () => {
it('attaches oauth listener to the Amplify singleton', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
} from '../utils/oauth';
import { createOAuthError } from '../utils/oauth/createOAuthError';
import { listenForOAuthFlowCancellation } from '../utils/oauth/cancelOAuthFlow';
import { ExtraQueryParameters } from '../../../types/inputs';

/**
* Signs in a user with OAuth. Redirects the application to an Identity Provider.
Expand Down Expand Up @@ -57,6 +58,7 @@ export async function signInWithRedirect(
provider,
customState: input?.customState,
preferPrivateSession: input?.options?.preferPrivateSession,
extraQueryParams: input?.extraQueryParams,
options: {
loginHint: input?.options?.loginHint,
lang: input?.options?.lang,
Expand All @@ -71,13 +73,15 @@ const oauthSignIn = async ({
clientId,
customState,
preferPrivateSession,
extraQueryParams,
options,
}: {
oauthConfig: OAuthConfig;
provider: string;
clientId: string;
customState?: string;
preferPrivateSession?: boolean;
extraQueryParams?: ExtraQueryParameters;
options?: SignInWithRedirectInput['options'];
}) => {
const { domain, redirectSignIn, responseType, scopes } = oauthConfig;
Expand Down Expand Up @@ -116,6 +120,7 @@ const oauthSignIn = async ({
code_challenge: toCodeChallenge(),
code_challenge_method: method,
}),
...extraQueryParams,
})
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&');
Expand Down
18 changes: 18 additions & 0 deletions packages/auth/src/types/inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ export interface AuthSignOutInput {

export type AuthProvider = 'Amazon' | 'Apple' | 'Facebook' | 'Google';

export type OAuthUrlReservedKeys =
| 'redirect_uri'
| 'response_type'
| 'client_id'
| 'identity_provider'
| 'scope'
| 'state'
| 'responseType';

/**
* User-defined custom query params for oAuthUrl.
*/
export type ExtraQueryParameters = Omit<
Record<string, string>,
OAuthUrlReservedKeys
>;

export interface AuthSignInWithRedirectInput {
provider?: AuthProvider | { custom: string };
customState?: string;
Expand Down Expand Up @@ -96,6 +113,7 @@ export interface AuthSignInWithRedirectInput {
*/
nonce?: string;
};
extraQueryParams?: ExtraQueryParameters;
}

/**
Expand Down