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

Remove connect, disconnect for session strategies #7971

Merged
merged 4 commits into from
Oct 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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