Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplified configuration of custom URLs [SDK-2264] #253

Closed
wants to merge 5 commits into from

Conversation

Widcket
Copy link
Contributor

@Widcket Widcket commented Jan 24, 2021

Description

If the developer set up their login handler URL to be something other than the default /api/auth/login, then they would have to pass the custom value on every call to withPageAuthRequired. Same if they wanted to customize the URL the user would be redirected to after login (the returnTo URL).

This PR moves the configuration of custom URLs out of withPageAuthRequired to the UserProvider on the client-side and the config object on the server-side. Plus it's now also possible to set them via environment variables that are accessible both on the server and the client, enabling the developer to just set them once in a single place. This results in an improved developer experience.

Also, it's possible to customize the profile handler URL via environment variable as well, saving the developer from having to pass it to the UserProvider.

Testing

  • This change adds test coverage for new/changed/fixed functionality

Checklist

  • I have added documentation for new/changed functionality in this PR or in auth0.com/docs
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not master

@Widcket Widcket added the review:medium Medium review label Jan 24, 2021
@Widcket Widcket requested a review from a team as a code owner January 24, 2021 00:02
@vercel
Copy link

vercel bot commented Jan 24, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/auth0/nextjs-auth0/ltubr1bh1
✅ Preview: https://nextjs-auth0-git-feature-simplify-configuration.auth0.vercel.app

@@ -164,7 +164,7 @@ export const get = (params: ConfigParameters = {}): Config => {
...params
};

const { value, error, warning } = paramsSchema.validate(config);
const { value, error, warning } = paramsSchema.validate(config, { allowUnknown: true });
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise the validation would fail because of the new extra fields.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with doing this is that we will disable a lot of the runtime checking of config, a user might now pass config.cookie.samesite (rather than sameSite) and get no feedback about whether they spelled the property correctly.

For security sensitive properties, this would be an issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue with that approach is that you can't really have a configuration object that is any different from the one the underlying session library uses. That's not flexible and is not really an option, as it's a hard coupling with that package. I don't think that being able to catch misspellings is worth trading off for that flexibility.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll come up with a solution for this and #253 (comment) and share it with you

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've put a branch here https://github.com/auth0/nextjs-auth0/tree/split-config

It should make it easier for you to add config that isn't used by the base auth0-session layer https://github.com/auth0/nextjs-auth0/blob/split-config/src/config.ts#L460 - I'll add a few more tests to the config module and raise a PR

@@ -39,6 +39,8 @@ import { LoginOptions, DeepPartial } from './auth0-session';
* - `AUTH0_IDP_LOGOUT`: See {@link idpLogout}
* - `AUTH0_ID_TOKEN_SIGNING_ALG`: See {@link idTokenSigningAlg}
* - `AUTH0_LEGACY_SAME_SITE_COOKIE`: See {@link legacySameSiteCookie}
* - `NEXT_PUBLIC_AUTH0_LOGIN`: See {@link Config.routes}
* - `NEXT_PUBLIC_AUTH0_POST_LOGIN_REDIRECT`: See {@link Config.routes}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not adding NEXT_PUBLIC_AUTH0_PROFILE here as it's not used server-side.

@@ -164,7 +164,7 @@ export const get = (params: ConfigParameters = {}): Config => {
...params
};

const { value, error, warning } = paramsSchema.validate(config);
const { value, error, warning } = paramsSchema.validate(config, { allowUnknown: true });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with doing this is that we will disable a lot of the runtime checking of config, a user might now pass config.cookie.samesite (rather than sameSite) and get no feedback about whether they spelled the property correctly.

For security sensitive properties, this would be an issue.

src/frontend/use-config.tsx Show resolved Hide resolved
loginUrl = '/api/auth/login'
} = options;
const { onRedirecting = defaultOnRedirecting, onError = defaultOnError } = options;
const { loginUrl, returnTo } = useConfig();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't centralise the returnTo option, there is still a use case for being able to customise it by route, eg for admin only route they might do:

withPageAuthRequired(AdminProfile, {
  returnTo: '/admin'
});

Copy link
Contributor Author

@Widcket Widcket Jan 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll re-add the config option so it's customizable by route. But still should be able to be centralizable for the majority of users that won't need page-specific overrides. You could have a central custom route, and change it for specific pages.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to insist that we don't have a centralised returnTo option, for these reasons:

  1. We don't have one in auth0-react's withAuthenticationRequired, auth0-angular's AuthGuard or express-openid-connect's requiresAuth - and AFAIK, we've never had a request for it
  2. It wouldn't be obvious from the name what a global returnTo option would be for (we accept a returnTo option in handleLogin, handleLogout and withPageAuthRequired)
  3. withPageAuthRequired has a default behaviour - returning to the url the user was trying to visit, adding a global option would disable this and be a source of confusion for developers
  4. We don't have a good use case for it
  5. It's easy to add this option if user's ask for it, but difficult to take away without a breaking change

@@ -90,22 +92,25 @@ export type WithPageAuthRequired = {
/**
* @ignore
*/
export default function withPageAuthRequiredFactory(sessionCache: SessionCache): WithPageAuthRequired {
export default function withPageAuthRequiredFactory(config: Config, sessionCache: SessionCache): WithPageAuthRequired {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to fix #154 (comment) - we're not going to be able to pass config in here.

Doing so would mean that withPageAuthRequiredCSR would require you to invoke the server side instance of the SDK at build time, which is not desirable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll use the environment variables directly then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using environment variables directly won't work for the case where user's create their own instance of the SDK using initAuth0({ routes: { loginUrl: ... }})

@@ -53,15 +53,15 @@ function getInstance(): SignInWithAuth0 {
}

export const initAuth0: InitAuth0 = (params) => {
const config = getConfig(getParams(params));
const config = getConfig(getParams(params)) as Config;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

casting this as Config will remove type checking for an important/complex object in the SDK. We should fix the type of this rather than cast it if it's wrong

Copy link
Contributor Author

@Widcket Widcket Jan 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is related to coupling this config object to the session package's one. As we're extending that config object, that should not be an issue because it still contains all the properties from the session package config. And therefore would still type-check (Config being a superset of the session package's config).

* Either a relative path to the application or a valid URI to an external domain.
* The user will be redirected to this after a login has been performed.
*/
postLoginRedirect: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to create a postLoginRedirect option, then it should work the same as postLogoutRedirect - in that it is the default in auth0-session#logout if returnTo is not set https://github.com/auth0/nextjs-auth0/blob/beta/src/auth0-session/handlers/logout.ts#L17

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I'll add it.

@@ -0,0 +1,22 @@
import React, { ReactElement, useContext, createContext } from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you exclude this file from the API Docs https://github.com/auth0/nextjs-auth0/blob/beta/typedoc.js#L4

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure 👍🏼

*
* ```js
* {
* response_type: 'code',
Copy link
Contributor

@adamjmcgrath adamjmcgrath Jan 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need to keep these docs for most of these properties because the defaults are different.

If you generate the docs now, it'll say the default response_type is id_token when it should be code https://github.com/auth0/nextjs-auth0/blob/beta/src/auth0-session/config.ts#L40

I also wanted to add the corresponding env vars to each config option, eg

    /**	
   * To opt-out of sending the library and node version to your authorization server	
   * via the `Auth0-Client` header. Default is `true	
   * You can also use the `AUTH0_ENABLE_TELEMETRY` env var
   */	
  enableTelemetry: boolean;

Also baseURL has some Vercel specific docs

@Widcket
Copy link
Contributor Author

Widcket commented Feb 2, 2021

Superseded by #262, #263 and #268.

@Widcket Widcket closed this Feb 2, 2021
@Widcket Widcket deleted the feature/simplify-configuration branch February 2, 2021 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review:medium Medium review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants