Skip to content

Commit

Permalink
Replace session-store-redis package with example (#7971)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown committed Oct 4, 2022
1 parent d096517 commit a8a5f1f
Show file tree
Hide file tree
Showing 23 changed files with 545 additions and 666 deletions.
5 changes: 5 additions & 0 deletions .changeset/rude-worms-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-6/core': major
---

Removes `connect` and `disconnect` from `SessionStore`
5 changes: 5 additions & 0 deletions .changeset/two-fishes-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-6/core': major
---

Removes `disconnect` from `SessionStrategy`
79 changes: 3 additions & 76 deletions .github/workflows/core_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
- uses: ./.github/actions/ci-setup

- name: Unit tests
run: yarn jest --ci --runInBand --shard=${{ matrix.index }}/9 api-tests --testPathIgnorePatterns=examples-smoke-tests --testPathIgnorePatterns=tests/api-tests/fields/crud --testPathIgnorePatterns=tests/api-tests/auth-stored-session.test.ts
run: yarn jest --ci --runInBand --shard=${{ matrix.index }}/9 api-tests --testPathIgnorePatterns=tests/api-tests/fields/crud
env:
TEST_ADAPTER: postgresql
DATABASE_URL: postgres://testuser:testpass@localhost:5432/test_db
Expand All @@ -57,7 +57,7 @@ jobs:
- uses: ./.github/actions/ci-setup

- name: Unit tests
run: yarn jest --ci --runInBand api-tests --shard=${{ matrix.index }}/9 --testPathIgnorePatterns=examples-smoke-tests --testPathIgnorePatterns=tests/api-tests/fields/crud --testPathIgnorePatterns=tests/api-tests/auth-stored-session.test.ts
run: yarn jest --ci --runInBand --shard=${{ matrix.index }}/9 api-tests --testPathIgnorePatterns=tests/api-tests/fields/crud
env:
TEST_ADAPTER: sqlite

Expand All @@ -83,80 +83,7 @@ jobs:
- uses: ./.github/actions/ci-setup

- name: Unit tests
run: yarn jest --ci --runInBand --shard=${{ matrix.index }}/9 api-tests --testPathIgnorePatterns=examples-smoke-tests --testPathIgnorePatterns=tests/api-tests/fields/crud --testPathIgnorePatterns=tests/api-tests/auth-stored-session.test.ts
env:
TEST_ADAPTER: mysql
DATABASE_URL: mysql://root:testpass@localhost:3306/test_db

redis_session_tests_postgresql:
name: Redis Session Tests PostgreSQL
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14
env:
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
POSTGRES_DB: test_db
ports:
- 5432:5432
redis:
image: redis:7
ports:
- 6379:6379
steps:
- name: Checkout Repo
uses: actions/checkout@v3

- uses: ./.github/actions/ci-setup

- name: Unit tests
run: yarn jest --ci --runInBand tests/api-tests/auth-stored-session.test.ts
env:
TEST_ADAPTER: postgresql
DATABASE_URL: postgres://testuser:testpass@localhost:5432/test_db

redis_session_tests_sqlite:
name: Redis Session Tests SQLite
runs-on: ubuntu-latest
services:
redis:
image: redis:7
ports:
- 6379:6379
steps:
- name: Checkout Repo
uses: actions/checkout@v3

- uses: ./.github/actions/ci-setup

- name: Unit tests
run: yarn jest --ci --runInBand tests/api-tests/auth-stored-session.test.ts
env:
TEST_ADAPTER: sqlite

redis_session_tests_mysql:
name: Redis Session Tests MySQL
runs-on: ubuntu-latest
services:
redis:
image: redis:7
ports:
- 6379:6379
mysql:
image: mariadb:10.9
env:
MYSQL_ROOT_PASSWORD: testpass
ports:
- 3306:3306
steps:
- name: Checkout Repo
uses: actions/checkout@v3

- uses: ./.github/actions/ci-setup

- name: Unit tests
run: yarn jest --ci --runInBand tests/api-tests/auth-stored-session.test.ts
run: yarn jest --ci --runInBand --shard=${{ matrix.index }}/9 api-tests --testPathIgnorePatterns=tests/api-tests/fields/crud
env:
TEST_ADAPTER: mysql
DATABASE_URL: mysql://root:testpass@localhost:3306/test_db
Expand Down
21 changes: 0 additions & 21 deletions .github/workflows/skip_core_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,6 @@ jobs:
- name: Skipped tests
run: echo "Skipped tests"

redis_session_tests_postgresql:
name: Redis Session Tests PostgreSQL
runs-on: ubuntu-latest
steps:
- name: Skipped tests
run: echo "Skipped tests"

redis_session_tests_sqlite:
name: Redis Session Tests SQLite
runs-on: ubuntu-latest
steps:
- name: Skipped tests
run: echo "Skipped tests"

redis_session_tests_mysql:
name: Redis Session Tests MySQL
runs-on: ubuntu-latest
steps:
- name: Skipped tests
run: echo "Skipped tests"

field_crud_tests_postgresql:
name: Field CRUD Tests PostgreSQL
runs-on: ubuntu-latest
Expand Down
21 changes: 0 additions & 21 deletions docs/pages/docs/config/session.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ A `SessionStore` object has the following interface:

```typescript
const store = {
connect: async () => { /* ... */ },
disconnect: async () => { /* ... */ },
set: async (sessionId, data) => { /* ... */ },
get: async (sessionId) => {
/* ... */
Expand All @@ -89,29 +87,10 @@ const store = {

Interface:

- `connect`: Connect to the session store.
- `disconnect`: Disconnect from the session store.
- `set`: Set a value `data` for the key `sessionId`.
- `get`: Get the `data` value associated with `sessionId`.
- `delete`: Delete the entry associated with `sessionId` from the session store.

Keystone provides a [Redis](https://redis.io/) based session store in the package `@keystone-6/session-store-redis`.

```typescript
import redis from 'redis';
import { redisSessionStore } from '@keystone-6/session-store-redis';
import { config } from '@keystone-6/core';
import { storedSessions } from '@keystone-6/core/session';

export default config({
session: storedSessions({
store: redisSessionStore({ client: redis.createClient() }),
/* ... */,
}),
/* ... */
});
```

## Session context

If you configure your Keystone session with session management then the [`KeystoneContext`](../context/overview) type will include three session related properties.
Expand Down
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ These examples showcase how Keystone works with other tools and frameworks and u
- [Task Manager](./task-manager): A simple task manager with Keystone
- [Blog](./blog): A simple blog with Keystone
- [Authentication](./with-auth): Add password-based authentication.
- [Redis session store](./redis-session-store): Add password-based authentication with a Redis session store.
- [Role based access control](./roles): Control list access based on user roles.
- [JSON field](./json): JSON field in schema.
- [`defaultValue`](./default-values): Default values in schema.
Expand Down
21 changes: 21 additions & 0 deletions examples/redis-session-store/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## Feature Example - Redis Session Store

This project demonstrates how to use create a custom session store with Redis.
It builds on the [Authentication](../with-auth) example.

## Instructions

To run this project, clone the Keystone repository locally, run `yarn` at the root of the repository then navigate to this directory and run:

```shell
yarn dev
```

This will start the Admin UI at [localhost:3000](http://localhost:3000).
You can use the Admin UI to create items in your database.

You can also access a GraphQL Playground at [localhost:3000/api/graphql](http://localhost:3000/api/graphql), which allows you to directly run GraphQL queries and mutations.

## Try it out in CodeSandbox 🧪

You can play with this example online in a web browser using the free [codesandbox.io](https://codesandbox.io/) service. To launch this example, open the URL <https://githubbox.com/keystonejs/keystone/tree/main/examples/with-auth>. You can also fork this sandbox to make your own changes.
62 changes: 62 additions & 0 deletions examples/redis-session-store/keystone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { config } from '@keystone-6/core';
import { storedSessions } from '@keystone-6/core/session';
import { createAuth } from '@keystone-6/auth';
import { createClient } from '@redis/client';
import { lists } from './schema';

// createAuth configures signin functionality based on the config below. Note this only implements
// authentication, i.e signing in as an item using identity and secret fields in a list. Session
// management and access control are controlled independently in the main keystone config.
const { withAuth } = createAuth({
// This is the list that contains items people can sign in as
listKey: 'Person',
// The identity field is typically a username or email address
identityField: 'email',
// The secret field must be a password type field
secretField: 'password',

// initFirstItem turns on the "First User" experience, which prompts you to create a new user
// when there are no items in the list yet
initFirstItem: {
// These fields are collected in the "Create First User" form
fields: ['name', 'email', 'password'],
},
});

const redis = createClient();

const session = storedSessions({
store: ({ maxAge }) => ({
async get(key) {
let result = await redis.get(key);
if (typeof result === 'string') {
return JSON.parse(result);
}
},
async set(key, value) {
await redis.setEx(key, maxAge, JSON.stringify(value));
},
async delete(key) {
await redis.del(key);
},
}),
// The session secret is used to encrypt cookie data (should be an environment variable)
secret: '-- EXAMPLE COOKIE SECRET; CHANGE ME --',
});

// We wrap our config using the withAuth function. This will inject all
// the extra config required to add support for authentication in our system.
export default withAuth(
config({
db: {
provider: 'sqlite',
url: process.env.DATABASE_URL || 'file:./keystone-example.db',
async onConnect() {
await redis.connect();
},
},
lists,
// We add our session configuration to the system here.
session,
})
);
20 changes: 20 additions & 0 deletions examples/redis-session-store/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@keystone-6/redis-session-store-example",
"version": "0.0.5",
"private": true,
"license": "MIT",
"scripts": {
"dev": "keystone dev",
"start": "keystone start",
"build": "keystone build"
},
"dependencies": {
"@keystone-6/auth": "^4.0.1",
"@keystone-6/core": "^2.2.0",
"@redis/client": "^1.3.0"
},
"devDependencies": {
"typescript": "~4.7.4"
},
"repository": "https://github.com/keystonejs/keystone/tree/main/examples/redis-session-store"
}
Loading

1 comment on commit a8a5f1f

@vercel
Copy link

@vercel vercel bot commented on a8a5f1f Oct 4, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.