Skip to content

Commit

Permalink
Publish experimental-custom-store tag for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
adamjmcgrath committed Dec 12, 2022
1 parent 6468115 commit c5b87d8
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 88 deletions.
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ workflows:
context:
- browserstack-env
- ship/node-publish:
publish-command: npm publish --tag experimental-custom-store
requires:
- build
context:
Expand All @@ -51,4 +52,4 @@ workflows:
filters:
branches:
only:
- main
- session-stores
156 changes: 79 additions & 77 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Examples

- [Basic Setup](#basic-setup)
- [Create your own instance of the SDK](#create-your-own-instance-of-the-sdk)
- [Customize handlers behavior](#customize-handlers-behavior)
- [Use custom auth urls](#use-custom-auth-urls)
- [Protecting a Server-Side Rendered (SSR) Page](#protecting-a-server-side-rendered-ssr-page)
- [Protecting a Client-Side Rendered (CSR) Page](#protecting-a-client-side-rendered-csr-page)
- [Protect an API Route](#protect-an-api-route)
- [Protecting pages with Middleware](#protecting-pages-with-middleware)
- [Access an External API from an API Route](#access-an-external-api-from-an-api-route)
- [Create your own instance of the SDK](#create-your-own-instance-of-the-sdk)
- [Add a signup handler](#add-a-signup-handler)
- [Use with Base Path and Internationalized Routing](#use-with-base-path-and-internationalized-routing)
- [Use a custom session store](#use-a-custom-session-store)
Expand Down Expand Up @@ -82,6 +82,79 @@ export default () => {

Have a look at the `basic-example` app [./examples/basic-example](./examples/basic-example).

## Create your own instance of the SDK

When you use the named exports, the SDK creates an instance of the SDK for you and configures it with the provided environment variables.

```js
// These named exports create and manage their own instance of the SDK configured with
// the provided `AUTH0_*` environment variables
import {
handleAuth,
handleLogin,
handleCallback,
handleLogout,
handleProfile,
withApiAuthRequired,
withPageAuthRequired,
getSession,
getAccessToken
} from '@auth0/nextjs-auth0';
```

However, there are various reasons why you might want to create and manage an instance of the SDK yourself:

- You may want to create your own instance for testing
- You may not want to use environment variables for the configuration of secrets (eg using CredStash or AWS's Key Management Service)
- You may be using a [custom session store](#use-a-custom-session-store) and need to provide the configuration as code.

In this case you can use the [initAuth0](https://auth0.github.io/nextjs-auth0/modules/instance.html) method to create an instance.

```js
// utils/auth0.js
import { initAuth0 } from '@auth0/nextjs-auth0';

export default initAuth0({
secret: 'LONG_RANDOM_VALUE',
issuerBaseURL: 'https://your-tenant.auth0.com',
baseURL: 'http://localhost:3000',
clientID: 'CLIENT_ID',
clientSecret: 'CLIENT_SECRET'
});
```

Now rather than using the named exports, you can use the instance methods directly.

```js
// pages/api/auth/[...auth0].js
import auth0 from '../../../utils/auth0';

// Use the instance method
export default auth0.handleAuth();
```

> Note: You should not use the instance methods in combination with the named exports,
> otherwise you will be creating multiple instances of the SDK. For example:
```js
// DON'T Mix instance methods and named exports
import auth0 from '../../../utils/auth0';
import { handleLogin } from '@auth0/nextjs-auth0';

export default auth0.handleAuth({
// <= instance method
async login(req, res) {
try {
// `auth0.handleAuth` and `handleLogin` will be using separate instances
// You should use `auth0.handleLogin` instead
await handleLogin(req, res); // <= named export
} catch (error) {
res.status(error.status || 400).end(error.message);
}
}
});
```

## Customize handlers behavior

Pass custom parameters to the auth handlers or add your own logging and error handling.
Expand Down Expand Up @@ -327,78 +400,6 @@ See a running example of the [API route acting as a proxy to an External API](./
- Check "Allow Offline Access" in your [API Settings](https://auth0.com/docs/get-started/apis/api-settings#access-settings)
- Make sure the "Refresh Token" grant is enabled in your [Application Settings](https://auth0.com/docs/get-started/applications/application-settings#grant-types) (this is the default)

## Create your own instance of the SDK

When you use the named exports, the SDK creates an instance of the SDK for you and configures it with the provided environment variables.

```js
// These named exports create and manage their own instance of the SDK configured with
// the provided `AUTH0_*` environment variables
import {
handleAuth,
handleLogin,
handleCallback,
handleLogout,
handleProfile,
withApiAuthRequired,
withPageAuthRequired,
getSession,
getAccessToken
} from '@auth0/nextjs-auth0';
```

However, there are various reasons why you might want to create and manage an instance of the SDK yourself:

- You may want to create your own instance for testing
- You may not want to use environment variables for the configuration of secrets (eg using CredStash or AWS's Key Management Service)

In this case you can use the [initAuth0](https://auth0.github.io/nextjs-auth0/modules/instance.html) method to create an instance.

```js
// utils/auth0.js
import { initAuth0 } from '@auth0/nextjs-auth0';

export default initAuth0({
secret: 'LONG_RANDOM_VALUE',
issuerBaseURL: 'https://your-tenant.auth0.com',
baseURL: 'http://localhost:3000',
clientID: 'CLIENT_ID',
clientSecret: 'CLIENT_SECRET'
});
```

Now rather than using the named exports, you can use the instance methods directly.

```js
// pages/api/auth/[...auth0].js
import auth0 from '../../../utils/auth0';

// Use the instance method
export default auth0.handleAuth();
```

> Note: You should not use the instance methods in combination with the named exports,
> otherwise you will be creating multiple instances of the SDK. For example:
```js
// DON'T Mix instance methods and named exports
import auth0 from '../../../utils/auth0';
import { handleLogin } from '@auth0/nextjs-auth0';

export default auth0.handleAuth({
// <= instance method
async login(req, res) {
try {
// `auth0.handleAuth` and `handleLogin` will be using separate instances
// You should use `auth0.handleLogin` instead
await handleLogin(req, res); // <= named export
} catch (error) {
res.status(error.status || 400).end(error.message);
}
}
});
```

# Add a signup handler

Pass a custom authorize parameter to the login handler in a custom route.
Expand Down Expand Up @@ -473,14 +474,14 @@ export const getServerSideProps = (ctx) => {

## Use a custom session store

You need to create your owm instance of the SDK in code, so you can pass an instance of your session store to the SDK's configuration.
You need to create your own instance of the SDK in code, so you can pass an instance of your session store to the SDK's configuration.

```typescript
// lib/auth0.ts
import { SessionStore, initAuth0 } from '@auth0/nextjs-auth0';
import { SessionStore, SessionStorePayload, initAuth0 } from '@auth0/nextjs-auth0';

class Store implements SessionStore {
private store: SomeSuitableKeyValueStoreLikeRedis;
private store: SomeSuitableKeyValueStoreLikeRedis<SessionStorePayload>;
constructor() {
// If you set the expiry accross the whole store use the session config,
// e.g. `min(config.session.rollingDuration, config.session.absoluteDuration)`
Expand All @@ -492,7 +493,8 @@ class Store implements SessionStore {
return val;
}
async set(id, val) {
// If you set the expiry per item, use `val.header.exp` (in secs)
// To set the expiry per item, use `val.header.exp` (in secs)
const expiryMs = val.header.exp * 1000;
await this.store.set(id, val);
}
async delete(id) {
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@auth0/nextjs-auth0",
"version": "2.0.1",
"version": "2.1.0-experimental-custom-store.0",
"description": "Next.js SDK for signing in with Auth0",
"exports": {
".": "./dist/index.js",
Expand Down
6 changes: 2 additions & 4 deletions src/auth0-session/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,9 @@ export interface SessionConfig {
store?: SessionStore<any>;

/**
* A Function for generating a session id when using a custom session store, this is
* required when you set {@Link SessionConfig.store}.
* A Function for generating a session id when using a custom session store.
*
* **IMPORTANT** You must use a suitable value from your platform to prevent collisions.
* e.g. for Node: `require('crypto').randomBytes(16).toString('hex')`
* **IMPORTANT** You must use a suitably unique value to prevent collisions.
*/
genid?: <Req = any>(req: Req) => string | Promise<string>;

Expand Down
2 changes: 1 addition & 1 deletion src/auth0-session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export {
ApplicationError
} from './utils/errors';
export { StatelessSession } from './session/stateless-session';
export { AbstractSession } from './session/abstract-session';
export { AbstractSession, SessionPayload } from './session/abstract-session';
export { StatefulSession, SessionStore } from './session/stateful-session';
export { default as TransientStore } from './transient-store';
export { Config, SessionConfig, CookieConfig, LoginOptions, LogoutOptions, AuthorizationParameters } from './config';
Expand Down
2 changes: 1 addition & 1 deletion src/auth0-session/session/stateful-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export class StatefulSession<
const cookieSetter = new this.Cookies();
const cookies = cookieSetter.getAll(req);
const keys = await this.getKeys();
const sessionId = (await getCookieValue(sessionName, cookies[sessionName], keys)) as string;
const sessionId = await getCookieValue(sessionName, cookies[sessionName], keys);

if (sessionId) {
debug('deleting session %o', sessionId);
Expand Down
2 changes: 1 addition & 1 deletion src/edge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export { WithMiddlewareAuthRequired };
let instance: Auth0Edge;

const genid = () => {
let bytes = new Uint8Array(16);
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
return Array.from(bytes)
.map((b) => b.toString(16).padStart(2, '0'))
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
StatelessSession,
StatefulSession,
SessionStore as GenericSessionStore,
SessionPayload,
TransientStore,
clientFactory,
loginHandler as baseLoginHandler,
Expand Down Expand Up @@ -265,4 +266,5 @@ export {
};

export type SessionStore = GenericSessionStore<Session>;
export type SessionStorePayload = SessionPayload<Session>;
/* c8 ignore stop */
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default '2.0.1';
export default '2.1.0-experimental-custom-store.0';

0 comments on commit c5b87d8

Please sign in to comment.