From 451c825c77cd68eafeb262eb1ea5cbfc21dce550 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Sat, 13 Feb 2021 01:21:36 +0300 Subject: Dynamically Show Discord OAuth Button Dynamically displays an auth button in place of the submit button if needed, and adds full authorization flow. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- src/pages/FormPage.tsx | 65 ++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) (limited to 'src/pages/FormPage.tsx') diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index c49b9fd..4237e86 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -9,10 +9,12 @@ import HeaderBar from "../components/HeaderBar"; import RenderedQuestion from "../components/Question"; import Loading from "../components/Loading"; import ScrollToTop from "../components/ScrollToTop"; +import OAuth2Button from "../components/OAuth2Button"; import { Form, FormFeatures, getForm } from "../api/forms"; +import { OAuthScopes, checkScopes } from "../api/auth"; import colors from "../colors"; -import { unselectable } from "../commonStyles"; +import { submitStyles, unselectable } from "../commonStyles"; interface PathParams { @@ -20,10 +22,13 @@ interface PathParams { } interface NavigationProps { - form_state: boolean // Whether the form is open or not + form_state: boolean, // Whether the form is open or not + scopes: OAuthScopes[] } class Navigation extends React.Component { + PAGE_PATH = "/form" + containerStyles = css` margin: auto; width: 50%; @@ -38,7 +43,7 @@ class Navigation extends React.Component { width: 50%; } - @media (max-width: 850px) { + @media (max-width: 870px) { width: 100%; > div { @@ -62,13 +67,13 @@ class Navigation extends React.Component { height: 0; display: none; - @media (max-width: 850px) { + @media (max-width: 870px) { display: block; } `; returnStyles = css` - padding: 0.5rem 2rem; + padding: 0.55rem 2.2rem; border-radius: 8px; color: white; @@ -83,36 +88,21 @@ class Navigation extends React.Component { } `; - submitStyles = css` - text-align: right; - - button { - padding: 0.5rem 4rem; - cursor: pointer; - - border: none; - border-radius: 8px; - - color: white; - font: inherit; - - background-color: ${colors.blurple}; - transition: background-color 300ms; - } - - button:hover { - background-color: ${colors.darkerBlurple}; - } - `; + constructor(props: NavigationProps) { + super(props); + this.setState({"logged_in": false}); + } render(): JSX.Element { let submit = null; + if (this.props.form_state) { - submit = ( -
- -
- ); + if (this.props.scopes.includes(OAuthScopes.Identify) && !checkScopes(this.props.scopes, this.PAGE_PATH)) { + // Render OAuth button if login is required, and the scopes needed are not available + submit = this.setState({"logged_in": true})}/>; + } else { + submit = ; + } } return ( @@ -121,7 +111,7 @@ class Navigation extends React.Component { Return Home
- { submit } +
{ submit }
); } @@ -146,7 +136,7 @@ const closedHeaderStyles = css` font-size: 1.5rem; background-color: ${colors.error}; - + @media (max-width: 500px) { padding: 1rem 1.5rem; } @@ -186,6 +176,13 @@ function FormPage(): JSX.Element { } const open: boolean = form.features.includes(FormFeatures.Open); + const require_auth: boolean = form.features.includes(FormFeatures.RequiresLogin); + + const scopes = []; + if (require_auth) { + scopes.push(OAuthScopes.Identify); + if (form.features.includes(FormFeatures.CollectEmail)) { scopes.push(OAuthScopes.Email); } + } let closed_header = null; if (!open) { @@ -201,7 +198,7 @@ function FormPage(): JSX.Element { { closed_header } { questions } - +
-- cgit v1.2.3 From fba316f235a3871743427f37b3bbd07bea6d77bd Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Wed, 17 Feb 2021 09:30:47 +0300 Subject: Removes Path From Auth Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- src/api/auth.ts | 23 +++++++++++------------ src/components/OAuth2Button.tsx | 5 ++--- src/pages/FormPage.tsx | 6 ++---- 3 files changed, 15 insertions(+), 19 deletions(-) (limited to 'src/pages/FormPage.tsx') diff --git a/src/api/auth.ts b/src/api/auth.ts index ad97e67..cfaa563 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -91,11 +91,11 @@ function ensureMinimumScopes(scopes: unknown, expected: OAuthScopes | OAuthScope /** * Return true if the program has the requested scopes or higher. */ -export function checkScopes(scopes?: OAuthScopes[], path = ""): boolean { +export function checkScopes(scopes?: OAuthScopes[]): boolean { const cleanedScopes = ensureMinimumScopes(scopes, OAuthScopes.Identify); // Get Active Scopes And Ensure Type - const cookies = new Cookies().get(CookieNames.Scopes + path); + const cookies = new Cookies().get(CookieNames.Scopes); if (!cookies || !Array.isArray(cookies)) { return false; } @@ -169,7 +169,7 @@ export async function getDiscordCode(scopes: OAuthScopes[]): Promise<{code: stri } /** - * Sends a discord code from a given path to the backend, + * Sends a discord code to the backend, * and returns the resultant JWT and expiry date. * * @throws { APIErrors } On error, the APIErrors.Message is set, and an APIErrors object is thrown. @@ -218,27 +218,26 @@ export async function requestBackendJWT(code: string): Promise { } /** - * Handle a full authorization flow. Sets a token for the specified path with the JWT and scopes. + * Handle a full authorization flow. Sets a cookie with the JWT and scopes. * * @param scopes The scopes that should be authorized for the application. * @param disableFunction An optional function that can disable a component while processing. - * @param path The site path to save the token under. * * @throws { APIErrors } See documentation on { requestBackendJWT }. */ -export default async function authorize(scopes: OAuthScopes[] = [], disableFunction?: (newState: boolean) => void, path = "/"): Promise { - if (!checkScopes(scopes, path)) { +export default async function authorize(scopes: OAuthScopes[] = [], disableFunction?: (newState: boolean) => void): Promise { + if (!checkScopes(scopes)) { const cookies = new Cookies; - cookies.remove(CookieNames.Token + path); - cookies.remove(CookieNames.Scopes + path); + cookies.remove(CookieNames.Token); + cookies.remove(CookieNames.Scopes); if (disableFunction) { disableFunction(true); } await getDiscordCode(scopes).then(async discord_response =>{ await requestBackendJWT(discord_response.code).then(backend_response => { - const options: CookieSetOptions = {sameSite: "strict", expires: backend_response.Expiry, secure: PRODUCTION, path: path}; + const options: CookieSetOptions = {sameSite: "strict", expires: backend_response.Expiry, secure: PRODUCTION}; - cookies.set(CookieNames.Token + path, backend_response.JWT, options); - cookies.set(CookieNames.Scopes + path, discord_response.cleanedScopes, options); + cookies.set(CookieNames.Token, backend_response.JWT, options); + cookies.set(CookieNames.Scopes, discord_response.cleanedScopes, options); }); }).finally(() => { if (disableFunction) { disableFunction(false); } diff --git a/src/components/OAuth2Button.tsx b/src/components/OAuth2Button.tsx index 1ee456c..25c5871 100644 --- a/src/components/OAuth2Button.tsx +++ b/src/components/OAuth2Button.tsx @@ -11,7 +11,6 @@ import { selectable } from "../commonStyles"; interface OAuth2ButtonProps { scopes?: OAuthScopes[], - path?: string, rerender: () => void } @@ -47,7 +46,7 @@ const errorStyles = css` `; async function login(props: OAuth2ButtonProps, errorDialog: React.RefObject, setDisabled: (newState: boolean) => void) { - await authenticate(props.scopes, setDisabled, props.path).catch((reason: APIErrors) => { + await authenticate(props.scopes, setDisabled).catch((reason: APIErrors) => { // Display Error Message if (errorDialog.current) { errorDialog.current.style.visibility = "visible"; @@ -60,7 +59,7 @@ async function login(props: OAuth2ButtonProps, errorDialog: React.RefObject { - PAGE_PATH = "/form" - containerStyles = css` margin: auto; width: 50%; @@ -97,9 +95,9 @@ class Navigation extends React.Component { let submit = null; if (this.props.form_state) { - if (this.props.scopes.includes(OAuthScopes.Identify) && !checkScopes(this.props.scopes, this.PAGE_PATH)) { + if (this.props.scopes.includes(OAuthScopes.Identify) && !checkScopes(this.props.scopes)) { // Render OAuth button if login is required, and the scopes needed are not available - submit = this.setState({"logged_in": true})}/>; + submit = this.setState({"logged_in": true})}/>; } else { submit = ; } -- cgit v1.2.3 From 9f04d5f5effd07534c9eb5b9f8886c8f970d0dc6 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Sun, 7 Mar 2021 00:46:47 +0300 Subject: Fixes Return Home Button Centering Fixes the centering of the return home button on closed forms, by removing the style wrapper. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- src/components/OAuth2Button.tsx | 6 +++--- src/pages/FormPage.tsx | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src/pages/FormPage.tsx') diff --git a/src/components/OAuth2Button.tsx b/src/components/OAuth2Button.tsx index 25c5871..885c080 100644 --- a/src/components/OAuth2Button.tsx +++ b/src/components/OAuth2Button.tsx @@ -31,16 +31,16 @@ const errorStyles = css` visibility: hidden; width: 100%; left: 0; - + text-align: center; white-space: normal; box-sizing: border-box; - + padding: 0 15rem; @media (max-width: 750px) { padding: 0 5rem; } - + color: red; margin-top: 2.5rem; `; diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index fa63282..8852ac5 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -96,12 +96,14 @@ class Navigation extends React.Component { let submit = null; if (this.props.form_state) { + let inner_submit; if (this.props.scopes.includes(OAuthScopes.Identify) && !checkScopes(this.props.scopes)) { // Render OAuth button if login is required, and the scopes needed are not available - submit = this.setState({"logged_in": true})}/>; + inner_submit = this.setState({"logged_in": true})}/>; } else { - submit = ; + inner_submit = ; } + submit =
{ inner_submit }
; } return ( @@ -110,7 +112,7 @@ class Navigation extends React.Component { Return Home

-
{ submit }
+ { submit } ); } -- cgit v1.2.3