Skip to content

Commit

Permalink
Feaute/asub 8252 Apple OIDC (#2193)
Browse files Browse the repository at this point in the history
* add apple oidc button

* add oidc logic

* update apple sign on to use OIDC if clientId is added

* add logic for when apple v1 is not available and OIDC is

* add tests for apple sign on

* update apple to use oidc sign in

* update identity and sales SDK versions

* add 1.89.0 sdk version
  • Loading branch information
accbjt authored Aug 30, 2024
1 parent bc8933f commit 2f46899
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 43 deletions.
14 changes: 10 additions & 4 deletions blocks/identity-block/components/login/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const useLogin = ({
loggedInPageLocation,
isOIDC,
appleCode,
appleState,
}) => {

const { Identity } = useIdentity();
Expand All @@ -32,8 +33,13 @@ const useLogin = ({
};

useEffect(() => {
const askForloginWithApple = async (code) => {
await Identity.appleSignOn(code);
const askForloginWithApple = async (code, state) => {
if (state) {
await Identity.signInWithOIDC(code, state);
} else {
await Identity.appleSignOn(code);
}

const isLoggedIn = await Identity.isLoggedIn();

if (isLoggedIn) {
Expand All @@ -42,9 +48,9 @@ const useLogin = ({
};

if (Identity && appleCode) {
askForloginWithApple(appleCode);
askForloginWithApple(appleCode, appleState);
}
}, [appleCode, Identity]);
}, [appleCode, Identity, appleState]);

useEffect(() => {
const searchParams = new URLSearchParams(window.location.search.substring(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,38 @@ import { SIGN_UP } from "../constants";

const AppleIcon = <Icon name="Apple" width={21} height={24} viewBox="0 0 24 24" />;

function AppleSignIn({ customButtons, socialSignOnIn, className }) {
function AppleSignIn({ customButtons, socialSignOnIn, className, oidcClients = [], appleClientId }) {
const phrases = usePhrases();
const { Identity } = useIdentity();

const appleOIDCClient = oidcClients.find((oidcClient) => {
const parsedClientId = oidcClient.clientId.split(';')[0];

return oidcClient.protocol === 'Apple' && parsedClientId === appleClientId;
});

const handleClick = () => {
if (appleOIDCClient?.clientId) {
Identity.initiateOIDC(
appleOIDCClient.clientId,
['name', 'email'],
true,
true
);
} else {
Identity.initAppleSignOn();
}
};

return (
<div
data-testid="apple-sign-in-button"
style={{ width: '100%' }}
>
<Button
id="apple-btn"
variant="secondary-reverse"
onClick={() => Identity.initAppleSignOn()}
onClick={handleClick}
iconLeft={AppleIcon}
className={`${className}__Apple ${customButtons ? `${className}__Apple__custom` : ''}`}
>
Expand All @@ -23,6 +46,7 @@ function AppleSignIn({ customButtons, socialSignOnIn, className }) {
<span>{phrases.t("identity-block.social-signOn-apple-signUp")}</span>
)}
</Button>
</div>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ jest.mock("@wpmedia/arc-themes-components", () => ({
Icon: () => <div data-testid="Apple-icon" />,
}));

const mockInitAppleSignOn = jest.fn();
const mockInitiateOIDCMock = jest.fn();

jest.mock("@wpmedia/arc-themes-components", () => ({
...jest.requireActual("@wpmedia/arc-themes-components"),
Icon: () => <div data-testid="Apple-icon" />,
useIdentity: () => {
const Identity = {
initiateOIDC: mockInitiateOIDCMock,
initAppleSignOn: mockInitAppleSignOn,
};
return { Identity };
},
}));

describe("Identity Social Login Component", () => {
beforeEach(() => {
jest.clearAllMocks();
Expand All @@ -37,4 +52,28 @@ describe("Identity Social Login Component", () => {
render(<AppleSignIn socialSignOnIn="SignUp" />);
expect(screen.getByText("identity-block.social-signOn-apple-signUp")).not.toBeNull();
});

it("triggers Identity.initiateOIDC when using Apple OIDC is used", () => {
render(<AppleSignIn socialSignOnIn="Login" oidcClients={[{ clientId: 'appleoidc', protocol: 'Apple' }]} appleClientId='appleoidc' />);
screen.getByText("identity-block.social-signOn-apple-login").click();
expect(mockInitiateOIDCMock).toHaveBeenCalled();
});

it("triggers Identity.initAppleSignOn when using Apple v1 sign on is used", () => {
render(<AppleSignIn socialSignOnIn="Login" />);
screen.getByText("identity-block.social-signOn-apple-login").click();
expect(mockInitAppleSignOn).toHaveBeenCalled();
});

it("triggers Identity.initAppleSignOn when clientId is not available in OIDC client list", () => {
render(<AppleSignIn socialSignOnIn="Login" oidcClients={[{ clientId: 'appleoidc', protocol: 'Apple' }]} appleClientId='noappleoidc' />);
screen.getByText("identity-block.social-signOn-apple-login").click();
expect(mockInitAppleSignOn).toHaveBeenCalled();
});

it("triggers Identity.initAppleSignOn when clientId is not a protocol: 'Apple'", () => {
render(<AppleSignIn socialSignOnIn="Login" oidcClients={[{ clientId: 'appleoidc', protocol: 'Default' }]} appleClientId='appleoidc' />);
screen.getByText("identity-block.social-signOn-apple-login").click();
expect(mockInitAppleSignOn).toHaveBeenCalled();
});
});
51 changes: 46 additions & 5 deletions blocks/identity-block/components/social-sign-on/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,60 @@ import GoogleSignIn from "./_children/GoogleSignIn";
import AppleSignIn from "./_children/AppleSignIn";
import useSocialSignIn from "./utils/useSocialSignIn";

const SocialSignOn = ({ className, onError, redirectURL, isOIDC, socialSignOnIn, customButtons }) => {
const { facebookAppId, googleClientId, appleTeamId, appleKeyId, appleUrlToReceiveAuthToken} = useSocialSignIn(redirectURL, isOIDC, socialSignOnIn, onError, customButtons);
const SocialSignOn = ({
className,
onError,
redirectURL,
isOIDC,
socialSignOnIn,
customButtons,
appleClientId,
}) => {
const {
facebookAppId,
googleClientId,
appleTeamId,
appleKeyId,
appleUrlToReceiveAuthToken,
oidcClients,
} = useSocialSignIn(redirectURL, isOIDC, socialSignOnIn, onError, customButtons);

const hasAppleClient = () => {
const hasOIDCAppleClient = oidcClients && oidcClients.find((oidcClient) => (
oidcClient.protocol === "Apple" && oidcClient.clientId === appleClientId
));

if (hasOIDCAppleClient) {
return true;
}

if (appleTeamId && appleKeyId && appleUrlToReceiveAuthToken) {
return true;
}

return false;
}

return (
<section className={className}>
{googleClientId ? <GoogleSignIn customButtons={customButtons} socialSignOnIn={socialSignOnIn} className={className} /> : null}
{facebookAppId ? <FacebookSignIn customButtons={customButtons} socialSignOnIn={socialSignOnIn} className={className} /> : null}
{appleTeamId && appleKeyId && appleUrlToReceiveAuthToken ? <AppleSignIn customButtons={customButtons} socialSignOnIn={socialSignOnIn} className={className} /> : null}
{googleClientId && <GoogleSignIn customButtons={customButtons} socialSignOnIn={socialSignOnIn} className={className} />}
{facebookAppId && <FacebookSignIn customButtons={customButtons} socialSignOnIn={socialSignOnIn} className={className} />}
{hasAppleClient() && (
<AppleSignIn
customButtons={customButtons}
socialSignOnIn={socialSignOnIn}
className={className}
oidcClients={oidcClients}
appleClientId={appleClientId}
/>
)}
</section>
);
};

SocialSignOn.propTypes = {
redirectURL: PropTypes.string.isRequired,
appleClientId: PropTypes.string,
onError: PropTypes.func.isRequired,
};

Expand Down
76 changes: 59 additions & 17 deletions blocks/identity-block/components/social-sign-on/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jest.mock('@wpmedia/arc-themes-components', () => ({
Button: (props) => mockButton(props),
useIdentity: jest.fn(),
usePhrases: jest.fn()
}));
}));

describe("Identity Social Login Component", () => {
it("renders nothing if config settings are false", () => {
Expand All @@ -24,8 +24,8 @@ describe("Identity Social Login Component", () => {
googleClientId: false,
facebookAppId: false,
},
initFacebookLogin: () => {},
initializeFacebook: () => {},
initFacebookLogin: () => { },
initializeFacebook: () => { },
},
}));
usePhrases.mockImplementation(() => ({
Expand Down Expand Up @@ -61,8 +61,8 @@ describe("Identity Social Login Component", () => {
recaptchaSiteKey: "6LdXKVQcAAAAAO2tv3GdUbSK-1vcgujX6cP0IgF_",
}),
),
initFacebookLogin: () => {},
initializeFacebook: () => {},
initFacebookLogin: () => { },
initializeFacebook: () => { },
isLoggedIn: jest.fn(() => false),
},
}));
Expand All @@ -82,8 +82,8 @@ describe("Identity Social Login Component", () => {
useIdentity.mockImplementation(() => ({
Identity: {
getConfig: getConfigMock,
initFacebookLogin: () => {},
initializeFacebook: () => {},
initFacebookLogin: () => { },
initializeFacebook: () => { },
isLoggedIn: jest.fn(() => false),
},
isInitialized: true,
Expand All @@ -110,9 +110,9 @@ describe("Identity Social Login Component", () => {
facebookAppId: true,
},
facebookSignOn: facebookSignOnMock,
getConfig: () => {},
initFacebookLogin: () => {},
initializeFacebook: () => {},
getConfig: () => { },
initFacebookLogin: () => { },
initializeFacebook: () => { },
isLoggedIn: jest.fn(() => false),
},
}));
Expand Down Expand Up @@ -140,9 +140,9 @@ describe("Identity Social Login Component", () => {
facebookAppId: true,
},
facebookSignOn: facebookSignOnMock,
getConfig: () => {},
initFacebookLogin: () => {},
initializeFacebook: () => {},
getConfig: () => { },
initFacebookLogin: () => { },
initializeFacebook: () => { },
isLoggedIn: jest.fn(() => false),
},
}));
Expand All @@ -162,6 +162,48 @@ describe("Identity Social Login Component", () => {
window.onFacebookSignOn();
expect(onErrorMock).toHaveBeenCalled();
});

it("renders Apple Sign in", () => {
useIdentity.mockImplementation(() => ({
isInitialized: true,
isLoggedIn: () => true,
Identity: {
configOptions: {
googleClientId: true,
facebookAppId: true,
teamId: "teamId",
keyId: "keyId",
urlToReceiveAuthToken: "urlToReceiveAuthToken",
oidcClients: [],
},
getConfig: jest.fn(() =>
Promise.resolve({
signinRecaptcha: false,
recaptchaSiteKey: "6LdXKVQcAAAAAO2tv3GdUbSK-1vcgujX6cP0IgF_",
}),
),
initFacebookLogin: () => { },
initializeFacebook: () => { },
isLoggedIn: jest.fn(() => false),
},
}));

usePhrases.mockImplementation(() => ({
t: jest
.fn()
.mockReturnValue(
"Sign-in prompt was suppressed by the user or dismissed. Please try again later or use another sign-in method.",
),
}));

render(
<GoogleSignInProvider>
<SocialSignOn onError={() => null} redirectURL="#" />
</GoogleSignInProvider>,
);

expect(screen.getByTestId("apple-sign-in-button")).toBeInTheDocument();
});
});

describe("Identity Social Login Component - Google Button", () => {
Expand All @@ -174,8 +216,8 @@ describe("Identity Social Login Component - Google Button", () => {
googleClientId: true,
facebookAppId: false,
},
initFacebookLogin: () => {},
initializeFacebook: () => {},
initFacebookLogin: () => { },
initializeFacebook: () => { },
},
}));
});
Expand Down Expand Up @@ -215,8 +257,8 @@ describe("Identity Social Login Component - Facebook Button", () => {
googleClientId: false,
facebookAppId: true,
},
initFacebookLogin: () => {},
initializeFacebook: () => {},
initFacebookLogin: () => { },
initializeFacebook: () => { },
},
}));
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ function useSocialSignIn(
appleTeamId: config.teamId,
appleKeyId: config.keyId,
appleUrlToReceiveAuthToken: config.urlToReceiveAuthToken,
oidcClients: config.oidcClients,
updateIdentities,
};
}
Expand Down
Loading

0 comments on commit 2f46899

Please sign in to comment.