Skip to content

Commit

Permalink
lint
Browse files Browse the repository at this point in the history
  • Loading branch information
yunakim714 committed Sep 26, 2024
1 parent 69166fc commit 171cff1
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 62 deletions.
55 changes: 0 additions & 55 deletions src/static/helpers/slasHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,61 +439,6 @@ describe('Registered B2C user flow', () => {
});
});

describe('Social login user flow', () => {
test('loginIDPUser does not stop when authorizeCustomer returns 303', async () => {
// slasClient is copied and tries to make an actual API call
const mockSlasClient = createMockSlasClient();
const {shortCode, organizationId} = mockSlasClient.clientConfig.parameters;

// Mock authorizeCustomer
nock(`https://${shortCode}.api.commercecloud.salesforce.com`)
.get(`/shopper/auth/v1/organizations/${organizationId}/oauth2/authorize`)
.query(true)
.reply(303, {message: 'Oh yes!'});

await expect(
slasHelper.loginIDPUser(mockSlasClient, {}, parameters)
).resolves.not.toThrow(ResponseError);
});

test('generates an access token using slas private client', async () => {
const mockSlasClient = createMockSlasClient();
const {shortCode, organizationId} = mockSlasClient.clientConfig.parameters;

// Mock authorizeCustomer
nock(`https://${shortCode}.api.commercecloud.salesforce.com`)
.get(`/shopper/auth/v1/organizations/${organizationId}/oauth2/authorize`)
.query(true)
.reply(303, {response_body: 'response_body'}, {location: url});

const accessToken = await slasHelper.loginIDPUser(
mockSlasClient,
credentialsPrivate,
parameters
);

const expectedReqOptions = {
headers: {
Authorization: `Basic ${stringToBase64(
`client_id:${credentialsPrivate.clientSecret}`
)}`,
},
body: {
grant_type: 'authorization_code',
redirect_uri: 'redirect_uri',
client_id: 'client_id',
channel_id: 'site_id',
usid: '048adcfb-aa93-4978-be9e-09cb569fdcb9',
code_verifier: expect.stringMatching(/./) as string,
code: 'J2lHm0cgXmnXpwDhjhLoyLJBoUAlBfxDY-AhjqGMC-o',
dnt: 'false',
},
};
expect(getAccessTokenMock).toBeCalledWith(expectedReqOptions);
expect(accessToken).toBe(expectedTokenResponse);
});
});

describe('authorizePasswordless is working', () => {
test('Correct parameters are used to call SLAS Client authorize', async () => {
const mockSlasClient = createMockSlasClient();
Expand Down
55 changes: 51 additions & 4 deletions src/static/helpers/slasHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ export async function authorize(
slasClientCopy.clientConfig.fetchOptions = {
...slasClient.clientConfig.fetchOptions,
redirect: isBrowser ? 'follow' : 'manual',
mode: 'no-cors',
};

const options = {
Expand All @@ -150,7 +149,6 @@ export async function authorize(
const redirectUrlString = response.headers?.get('location') || response.url;
const redirectUrl = new URL(redirectUrlString);
const searchParams = Object.fromEntries(redirectUrl.searchParams.entries());
const {headers} = response;

// url is a read only property we unfortunately cannot mock out using nock
// meaning redirectUrl will not have a falsy value for unit tests
Expand All @@ -161,10 +159,59 @@ export async function authorize(

return {
url: redirectUrlString,
...getCodeAndUsidFromUrl(redirectUrlString)
...getCodeAndUsidFromUrl(redirectUrlString),
};
}

/**
* Wrapper for the authorization endpoint. For federated login (3rd party IDP non-guest), the caller should redirect the user to the url in the url field of the returned object. The url will be the login page for the 3rd party IDP and the user will be sent to the redirectURI on success. Guest sessions return the code and usid directly with no need to redirect.
* @param slasClient a configured instance of the ShopperLogin SDK client
* @param codeVerifier - random string created by client app to use as a secret in the request
* @param parameters - Request parameters used by the `authorizeCustomer` endpoint.
* @param parameters.redirectURI - the location the client will be returned to after successful login with 3rd party IDP. Must be registered in SLAS.
* @param parameters.hint? - optional string to hint at a particular IDP. Guest sessions are created by setting this to 'guest'
* @param parameters.usid? - optional saved SLAS user id to link the new session to a previous session
* @returns login url, user id and authorization code if available
*/
export async function authorizeIDP(
slasClient: ShopperLogin<{
shortCode: string;
organizationId: string;
clientId: string;
siteId: string;
}>,
credentials: {
clientSecret?: string;
},
parameters: {
redirectURI: string;
hint: string;
usid?: string;
}
): Promise<string> {
const codeVerifier = createCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);

const privateClient = !!credentials.clientSecret;

const options = {
parameters: {
client_id: slasClient.clientConfig.parameters.clientId,
channel_id: slasClient.clientConfig.parameters.siteId,
...(!privateClient && {code_challenge: codeChallenge}),
hint: parameters.hint,
organizationId: slasClient.clientConfig.parameters.organizationId,
redirect_uri: parameters.redirectURI,
response_type: 'code',
...(parameters.usid && {usid: parameters.usid}),
},
};

const url = await slasClient.authorizeCustomer(options, true, true);

return url.toString();
}

/**
* A single function to execute the ShopperLogin Private Client Guest Login as described in the [API documentation](https://developer.salesforce.com/docs/commerce/commerce-api/guide/slas-private-client.html).
* **Note**: this func can run on client side. Only use this one when the slas client secret is secured.
Expand Down Expand Up @@ -657,4 +704,4 @@ export function logout(
channel_id: slasClient.clientConfig.parameters.siteId,
},
});
}
}
14 changes: 11 additions & 3 deletions templates/operations.ts.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
* @param body - The data to send as the request body.
{{/if}}
* @param rawResponse - Set to true to return entire Response object instead of DTO.
* @param rawURL - Set to true to return the Request URL
* @returns A promise of type Response if rawResponse is true, a promise of type {{getReturnTypeFromOperation this}} otherwise.
* {{#if (eq (lowercase @root.metadata.categories.[CC Version Status].[0]) "beta")}}
* @beta
Expand All @@ -79,7 +80,8 @@
body: {{{getPayloadTypeFromRequest request}}}
{{/if}}
}>,
rawResponse?: T
rawResponse?: T,
rawURL?: T
): Promise<T extends true ? Response : {{getReturnTypeFromOperation this}}>;

/**
Expand All @@ -99,6 +101,7 @@
* @param body - The data to send as the request body.
{{/if}}
* @param rawResponse - Set to true to return entire Response object instead of DTO.
* @param rawURL - Set to true to return the Request URL
*
* @returns A promise of type Response if rawResponse is true, a promise of type {{getReturnTypeFromOperation this}} otherwise.
* {{#if (eq (lowercase @root.metadata.categories.[CC Version Status].[0]) "beta")}}
Expand All @@ -120,8 +123,9 @@
body: {{{getPayloadTypeFromRequest request}}}
{{/if}}
}>,
rawResponse?: boolean
): Promise<Response | {{getReturnTypeFromOperation this}}> {
rawResponse?: boolean,
rawURL?: boolean
): Promise<Response | {{getReturnTypeFromOperation this}} | TemplateURL> {
const optionParams = options?.parameters || ({} as Partial<NonNullable<NonNullable<typeof options>["parameters"]>>);
const configParams = this.clientConfig.parameters;

Expand Down Expand Up @@ -175,6 +179,10 @@
}
);

if (rawURL) {
return url
}

const headers: Record<string, string> = {
{{#if (isRequestWithPayload request)}}
"Content-Type": "{{{getMediaTypeFromRequest request}}}",
Expand Down

0 comments on commit 171cff1

Please sign in to comment.