[next] Admin Authentication (#2155)

* feat: Support sign in via E-Mail, and social logins + permission check

* feat: no permission info

* test: unit test

* test: fix remaining tests

* test: add integration tests

* feat: add admin account completion

* test: auth completion feature tests

* fix: translation

* fix: comment marker design

* fix: linting issues

* chore: address pr review comments

* chore: add comment
This commit is contained in:
Kiwi
2019-02-04 21:26:41 +00:00
committed by Wyatt Johnson
parent 939152ee81
commit 7e8ef2189d
143 changed files with 5991 additions and 2048 deletions
@@ -0,0 +1,16 @@
.variantFilled {
&.colorRegular {
background-color: #3b5998;
}
&:not(.disabled) {
&.colorRegular {
&.mouseHover {
background-color: #4467b0;
}
&:active,
&.active {
background-color: #6583c3;
}
}
}
}
@@ -0,0 +1,17 @@
import { noop } from "lodash";
import React from "react";
import { createRenderer } from "react-test-renderer/shallow";
import { PropTypesOf } from "talk-framework/types";
import FacebookButton from "./FacebookButton";
it("renders correctly", () => {
const props: PropTypesOf<typeof FacebookButton> = {
onClick: noop,
children: "Login with Facebook",
};
const renderer = createRenderer();
renderer.render(<FacebookButton {...props} />);
expect(renderer.getRenderOutput()).toMatchSnapshot();
});
@@ -0,0 +1,42 @@
import React from "react";
import { StatelessComponent } from "react";
import { PropTypesOf } from "talk-framework/types";
import { Button } from "talk-ui/components";
import styles from "./FacebookButton.css";
interface Props {
onClick: PropTypesOf<typeof Button>["onClick"];
children: React.ReactNode;
}
const facebookIcon = (
<svg
width="17"
height="17"
viewBox="0 0 17 17"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16.0893 1.25391C16.0893 1.00781 15.9838 0.796875 15.808 0.621094C15.6323 0.480469 15.4213 0.375 15.2104 0.375H1.21819C0.936942 0.375 0.726005 0.480469 0.58538 0.621094C0.409598 0.796875 0.339286 1.00781 0.339286 1.25391V15.2461C0.339286 15.4922 0.409598 15.7031 0.58538 15.8789C0.726005 16.0547 0.936942 16.125 1.21819 16.125H8.74163V10.0078H6.70257V7.65234H8.74163V5.89453C8.74163 4.91016 9.02288 4.13672 9.58538 3.57422C10.1479 3.04688 10.8862 2.76562 11.8002 2.76562C12.5033 2.76562 13.1362 2.80078 13.6283 2.83594V4.98047H12.3627C11.9057 4.98047 11.5893 5.08594 11.4135 5.29688C11.2729 5.47266 11.2026 5.75391 11.2026 6.14062V7.65234H13.558L13.2416 10.0078H11.2026V16.125H15.2104C15.4565 16.125 15.6674 16.0547 15.8432 15.8789C15.9838 15.7031 16.0893 15.4922 16.0893 15.2461V1.25391Z"
fill="white"
/>
</svg>
);
const FacebookButton: StatelessComponent<Props> = props => (
<Button
classes={styles}
variant="filled"
size="large"
fullWidth
onClick={props.onClick}
>
{facebookIcon}
<span>{props.children}</span>
</Button>
);
export default FacebookButton;
@@ -0,0 +1,16 @@
.variantFilled {
&.colorRegular {
background-color: #db4437;
}
&:not(.disabled) {
&.colorRegular {
&.mouseHover {
background-color: #e05f54;
}
&:active,
&.active {
background-color: #e57a71;
}
}
}
}
@@ -0,0 +1,17 @@
import { noop } from "lodash";
import React from "react";
import { createRenderer } from "react-test-renderer/shallow";
import { PropTypesOf } from "talk-framework/types";
import GoogleButton from "./GoogleButton";
it("renders correctly", () => {
const props: PropTypesOf<typeof GoogleButton> = {
onClick: noop,
children: "Login with Google",
};
const renderer = createRenderer();
renderer.render(<GoogleButton {...props} />);
expect(renderer.getRenderOutput()).toMatchSnapshot();
});
@@ -0,0 +1,42 @@
import React from "react";
import { StatelessComponent } from "react";
import { PropTypesOf } from "talk-framework/types";
import { Button } from "talk-ui/components";
import styles from "./GoogleButton.css";
interface Props {
onClick: PropTypesOf<typeof Button>["onClick"];
children: React.ReactNode;
}
const googleIcon = (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.2924 9.46094C17.2924 9.00391 17.2221 8.51172 17.1518 7.98438H8.85491V11.0078H13.8119C13.7065 11.5352 13.4955 12.0625 13.2143 12.5547C12.7924 13.1875 12.2651 13.7148 11.6323 14.0664C10.8237 14.5586 9.9096 14.7695 8.85491 14.7695C7.87054 14.7695 6.95647 14.5234 6.14788 14.0312C5.30413 13.5391 4.67132 12.8711 4.17913 12.0273C3.68694 11.1836 3.44085 10.2695 3.44085 9.25C3.44085 8.08984 3.75725 7.03516 4.39007 6.12109C4.95257 5.27734 5.726 4.64453 6.71038 4.22266C7.6596 3.80078 8.64397 3.66016 9.62835 3.80078C10.683 3.94141 11.5619 4.39844 12.3354 5.10156L14.6908 2.81641C13.0737 1.30469 11.1049 0.53125 8.85491 0.53125C7.27288 0.53125 5.83147 0.953125 4.49554 1.72656C3.1596 2.5 2.06975 3.55469 1.29632 4.89062C0.52288 6.22656 0.136161 7.70312 0.136161 9.25C0.136161 10.832 0.52288 12.2734 1.29632 13.6094C2.06975 14.9453 3.1596 16.0352 4.49554 16.8086C5.83147 17.582 7.27288 17.9688 8.85491 17.9688C10.5073 17.9688 11.9838 17.6172 13.2494 16.8789C14.5151 16.1758 15.5346 15.1562 16.2377 13.8555C16.9408 12.5898 17.2924 11.1133 17.2924 9.46094Z"
fill="white"
/>
</svg>
);
const GoogleButton: StatelessComponent<Props> = props => (
<Button
classes={styles}
variant="filled"
size="large"
fullWidth
onClick={props.onClick}
>
{googleIcon}
<span>{props.children}</span>
</Button>
);
export default GoogleButton;
@@ -0,0 +1,16 @@
.variantFilled {
&.colorRegular {
background-color: #0d5b8f;
}
&:not(.disabled) {
&.colorRegular {
&.mouseHover {
background-color: #106fae;
}
&:active,
&.active {
background-color: #1383cd;
}
}
}
}
@@ -0,0 +1,17 @@
import { noop } from "lodash";
import React from "react";
import { createRenderer } from "react-test-renderer/shallow";
import { PropTypesOf } from "talk-framework/types";
import OIDCButton from "./OIDCButton";
it("renders correctly", () => {
const props: PropTypesOf<typeof OIDCButton> = {
onClick: noop,
children: "Login with OIDC",
};
const renderer = createRenderer();
renderer.render(<OIDCButton {...props} />);
expect(renderer.getRenderOutput()).toMatchSnapshot();
});
@@ -0,0 +1,26 @@
import React from "react";
import { StatelessComponent } from "react";
import { PropTypesOf } from "talk-framework/types";
import { Button } from "talk-ui/components";
import styles from "./OIDCButton.css";
interface Props {
onClick: PropTypesOf<typeof Button>["onClick"];
children: React.ReactNode;
}
const OIDCButton: StatelessComponent<Props> = props => (
<Button
classes={styles}
variant="filled"
size="large"
fullWidth
onClick={props.onClick}
>
<span>{props.children}</span>
</Button>
);
export default OIDCButton;
@@ -0,0 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders correctly 1`] = `
<withPropsOnChange(Button)
classes={
Object {
"active": "FacebookButton-active",
"colorRegular": "FacebookButton-colorRegular",
"disabled)": "FacebookButton-disabled)",
"mouseHover": "FacebookButton-mouseHover",
"variantFilled": "FacebookButton-variantFilled",
}
}
fullWidth={true}
onClick={[Function]}
size="large"
variant="filled"
>
<svg
fill="none"
height="17"
viewBox="0 0 17 17"
width="17"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16.0893 1.25391C16.0893 1.00781 15.9838 0.796875 15.808 0.621094C15.6323 0.480469 15.4213 0.375 15.2104 0.375H1.21819C0.936942 0.375 0.726005 0.480469 0.58538 0.621094C0.409598 0.796875 0.339286 1.00781 0.339286 1.25391V15.2461C0.339286 15.4922 0.409598 15.7031 0.58538 15.8789C0.726005 16.0547 0.936942 16.125 1.21819 16.125H8.74163V10.0078H6.70257V7.65234H8.74163V5.89453C8.74163 4.91016 9.02288 4.13672 9.58538 3.57422C10.1479 3.04688 10.8862 2.76562 11.8002 2.76562C12.5033 2.76562 13.1362 2.80078 13.6283 2.83594V4.98047H12.3627C11.9057 4.98047 11.5893 5.08594 11.4135 5.29688C11.2729 5.47266 11.2026 5.75391 11.2026 6.14062V7.65234H13.558L13.2416 10.0078H11.2026V16.125H15.2104C15.4565 16.125 15.6674 16.0547 15.8432 15.8789C15.9838 15.7031 16.0893 15.4922 16.0893 15.2461V1.25391Z"
fill="white"
/>
</svg>
<span>
Login with Facebook
</span>
</withPropsOnChange(Button)>
`;
@@ -0,0 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders correctly 1`] = `
<withPropsOnChange(Button)
classes={
Object {
"active": "GoogleButton-active",
"colorRegular": "GoogleButton-colorRegular",
"disabled)": "GoogleButton-disabled)",
"mouseHover": "GoogleButton-mouseHover",
"variantFilled": "GoogleButton-variantFilled",
}
}
fullWidth={true}
onClick={[Function]}
size="large"
variant="filled"
>
<svg
fill="none"
height="18"
viewBox="0 0 18 18"
width="18"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.2924 9.46094C17.2924 9.00391 17.2221 8.51172 17.1518 7.98438H8.85491V11.0078H13.8119C13.7065 11.5352 13.4955 12.0625 13.2143 12.5547C12.7924 13.1875 12.2651 13.7148 11.6323 14.0664C10.8237 14.5586 9.9096 14.7695 8.85491 14.7695C7.87054 14.7695 6.95647 14.5234 6.14788 14.0312C5.30413 13.5391 4.67132 12.8711 4.17913 12.0273C3.68694 11.1836 3.44085 10.2695 3.44085 9.25C3.44085 8.08984 3.75725 7.03516 4.39007 6.12109C4.95257 5.27734 5.726 4.64453 6.71038 4.22266C7.6596 3.80078 8.64397 3.66016 9.62835 3.80078C10.683 3.94141 11.5619 4.39844 12.3354 5.10156L14.6908 2.81641C13.0737 1.30469 11.1049 0.53125 8.85491 0.53125C7.27288 0.53125 5.83147 0.953125 4.49554 1.72656C3.1596 2.5 2.06975 3.55469 1.29632 4.89062C0.52288 6.22656 0.136161 7.70312 0.136161 9.25C0.136161 10.832 0.52288 12.2734 1.29632 13.6094C2.06975 14.9453 3.1596 16.0352 4.49554 16.8086C5.83147 17.582 7.27288 17.9688 8.85491 17.9688C10.5073 17.9688 11.9838 17.6172 13.2494 16.8789C14.5151 16.1758 15.5346 15.1562 16.2377 13.8555C16.9408 12.5898 17.2924 11.1133 17.2924 9.46094Z"
fill="white"
/>
</svg>
<span>
Login with Google
</span>
</withPropsOnChange(Button)>
`;
@@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders correctly 1`] = `
<withPropsOnChange(Button)
classes={
Object {
"active": "OIDCButton-active",
"colorRegular": "OIDCButton-colorRegular",
"disabled)": "OIDCButton-disabled)",
"mouseHover": "OIDCButton-mouseHover",
"variantFilled": "OIDCButton-variantFilled",
}
}
fullWidth={true}
onClick={[Function]}
size="large"
variant="filled"
>
<span>
Login with OIDC
</span>
</withPropsOnChange(Button)>
`;
@@ -1,2 +1,5 @@
export { default as CopyButton } from "./CopyButton";
export { default as PasswordField } from "./PasswordField";
export { default as FacebookButton } from "./FacebookButton";
export { default as GoogleButton } from "./GoogleButton";
export { default as OIDCButton } from "./OIDCButton";