Skip to content

Commit

Permalink
Merge pull request #476 from auth0/beta
Browse files Browse the repository at this point in the history
  • Loading branch information
ewanharris authored Jan 19, 2023
2 parents 2ee0e6e + 13d8b70 commit 24deb27
Show file tree
Hide file tree
Showing 51 changed files with 7,629 additions and 8,105 deletions.
8 changes: 6 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ orbs:
parameters:
docker_image:
type: string
default: cimg/node:16.17-browsers
default: cimg/node:18.12-browsers
jobs:
build:
docker:
- image: << pipeline.parameters.docker_image >>
resource_class: xlarge
steps:
- checkout
- restore_cache:
Expand Down Expand Up @@ -49,7 +50,7 @@ jobs:
- restore_cache:
key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-{{ checksum "examples/cra-react-router/package.json" }}-{{ checksum "examples/gatsby-app/package.json" }}-{{ checksum "examples/nextjs-app/package.json" }}-{{ checksum "examples/users-api/package-lock.json" }}
- run: npm ci
- run: npx concurrently --raw --kill-others --success first "npm:start" "wait-on http://127.0.0.1:3000/ && browserstack-cypress run --build-name $CIRCLE_BRANCH --specs "cypress/integration/smoke-bs.test.ts""
- run: npx concurrently --raw --kill-others --success first "npm:start" "wait-on http://127.0.0.1:3000/ && browserstack-cypress run --build-name $CIRCLE_BRANCH --no-wrap --specs "cypress/integration/smoke-bs.test.ts""

workflows:
Build and Test:
Expand All @@ -61,12 +62,15 @@ workflows:
context:
- browserstack-env
- ship/node-publish:
publish-command: npm publish --tag beta
node-version: 18.12.1
context:
- publish-npm
- publish-gh
filters:
branches:
only:
- master
- beta
requires:
- browserstack
12 changes: 6 additions & 6 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: "CodeQL"
name: 'CodeQL'

on:
push:
branches: [ "master", "beta" ]
branches: ['master', 'beta']
pull_request:
branches: [ "master" ]
branches: ['master']
schedule:
- cron: "37 10 * * 2"
- cron: '37 10 * * 2'

jobs:
analyze:
Expand All @@ -20,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ javascript ]
language: [javascript]

steps:
- name: Checkout
Expand All @@ -38,4 +38,4 @@ jobs:
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{ matrix.language }}"
category: '/language:${{ matrix.language }}'
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Change Log

## [v2.0.0-beta.0](https://github.com/auth0/auth0-react/tree/v2.0.0-beta.0) (2022-12-12)

Auth0-React v2 includes many significant changes compared to v1:

- Removal of polyfills from bundles
- Introduction of `authorizationParams` and `logoutParams` for properties sent to Auth0
- Removal of `buildAuthorizeUrl` and `buildLogoutUrl`
- Removal of `redirectMethod` on `loginWithRedirect` in favour of `openUrl`
- Removal of `localOnly` from `logout` in favour of `openUrl`
- Renaming of `ignoreCache` to `cacheMode` and introduction of `cache-only`
- Use `application/x-www-form-urlencoded` by default
- Do not fallback to refreshing tokens via iframe by default
- Changes to default scopes and removal of `advancedOptions.defaultScope`
- Removal of `claimCheck` on `withAuthenticationRequired`

As with any major version bump, v2 of Auth0-React contains a set of breaking changes. **Please review [the migration guide](./MIGRATION_GUIDE.md) thoroughly to understand the changes required to migrate your application to v2.**

## [v1.12.1](https://github.com/auth0/auth0-react/tree/v1.12.1) (2023-01-12)
[Full Changelog](https://github.com/auth0/auth0-react/compare/v1.12.0...v1.12.1)

Expand Down
145 changes: 39 additions & 106 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ const Posts = () => {
(async () => {
try {
const token = await getAccessTokenSilently({
audience: 'https://api.example.com/',
scope: 'read:posts',
authorizationParams: {
audience: 'https://api.example.com/',
scope: 'read:posts',
},
});
const response = await fetch('https://api.example.com/posts', {
headers: {
Expand All @@ -72,6 +74,7 @@ const Posts = () => {
});
setPosts(await response.json());
} catch (e) {
// Handle errors such as `login_required` and `consent_required` by re-prompting for a login
console.error(e);
}
})();
Expand Down Expand Up @@ -132,7 +135,9 @@ export default function App() {
<Auth0ProviderWithRedirectCallback
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
redirectUri={window.location.origin}
authorizationParams={{
redirect_uri: window.location.origin,
}}
>
<Routes>
<Route path="/" exact />
Expand Down Expand Up @@ -171,8 +176,10 @@ export const wrapRootElement = ({ element }) => {
<Auth0Provider
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
redirectUri={window.location.origin}
onRedirectCallback={onRedirectCallback}
authorizationParams={{
redirect_uri: window.location.origin,
}}
>
{element}
</Auth0Provider>
Expand Down Expand Up @@ -228,10 +235,11 @@ class MyApp extends App {
<Auth0Provider
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
redirectUri={
typeof window !== 'undefined' ? window.location.origin : undefined
}
onRedirectCallback={onRedirectCallback}
authorizationParams={{
redirect_uri:
typeof window !== 'undefined' ? window.location.origin : undefined,
}}
>
<Component {...pageProps} />
</Auth0Provider>
Expand Down Expand Up @@ -265,104 +273,6 @@ export default withAuthenticationRequired(Profile);
See [Next.js example app](./examples/nextjs-app)
## Create a `useApi` hook for accessing protected APIs with an access token.
```js
// use-api.js
import { useEffect, useState } from 'react';
import { useAuth0 } from '@auth0/auth0-react';

export const useApi = (url, options = {}) => {
const { getAccessTokenSilently } = useAuth0();
const [state, setState] = useState({
error: null,
loading: true,
data: null,
});
const [refreshIndex, setRefreshIndex] = useState(0);

useEffect(() => {
(async () => {
try {
const { audience, scope, ...fetchOptions } = options;
const accessToken = await getAccessTokenSilently({ audience, scope });
const res = await fetch(url, {
...fetchOptions,
headers: {
...fetchOptions.headers,
// Add the Authorization header to the existing headers
Authorization: `Bearer ${accessToken}`,
},
});
setState({
...state,
data: await res.json(),
error: null,
loading: false,
});
} catch (error) {
setState({
...state,
error,
loading: false,
});
}
})();
}, [refreshIndex]);

return {
...state,
refresh: () => setRefreshIndex(refreshIndex + 1),
};
};
```
Then use it for accessing protected APIs from your components:
```jsx
// users.js
import { useApi } from './use-api';

export const Profile = () => {
const opts = {
audience: 'https://api.example.com/',
scope: 'read:users',
};
const { login, getAccessTokenWithPopup } = useAuth0();
const {
loading,
error,
refresh,
data: users,
} = useApi('https://api.example.com/users', opts);
const getTokenAndTryAgain = async () => {
await getAccessTokenWithPopup(opts);
refresh();
};
if (loading) {
return <div>Loading...</div>;
}
if (error) {
if (error.error === 'login_required') {
return <button onClick={() => login(opts)}>Login</button>;
}
if (error.error === 'consent_required') {
return (
<button onClick={getTokenAndTryAgain}>Consent to reading users</button>
);
}
return <div>Oops {error.message}</div>;
}
return (
<ul>
{users.map((user, index) => {
return <li key={index}>{user}</li>;
})}
</ul>
);
};
```
## Use with Auth0 organizations
[Organizations](https://auth0.com/docs/organizations) is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications. Note that Organizations is currently only available to customers on our Enterprise and Startup subscription plans.
Expand All @@ -375,8 +285,10 @@ ReactDOM.render(
<Auth0Provider
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
redirectUri={window.location.origin}
organization="YOUR_ORGANIZATION_ID"
authorizationParams={{
redirectUri: window.location.origin,
}}
>
<App />
</Auth0Provider>
Expand Down Expand Up @@ -406,3 +318,24 @@ const App = () => {
return <div>...</div>;
};
```
## Protecting a route with a claims check
In order to protect a route with a claims check alongside an authentication required check, you can create a HOC that will wrap your component and use that to check that the user has the required claims.
```jsx
const withClaimCheck = (Component, myClaimCheckFunction, returnTo) => {
const { user } = useAuth0();
if (myClaimCheckFunction(user)) {
return <Component />
}
Router.push(returnTo);
}

const checkClaims = (claim?: User) => claim?.['https://my.app.io/jwt/claims']?.ROLE?.includes('ADMIN');

// Usage
const Page = withAuthenticationRequired(
withClaimCheck(Component, checkClaims, '/missing-roles' )
);
```
Loading

0 comments on commit 24deb27

Please sign in to comment.