Skip to content

Commit 7d419f8

Browse files
fauna-brechtMatthew SweeneyTimer
committed
Let users define their own database as easily as possible. (vercel#10209)
* Let users define their own client token. * Make sure users know that GraphQL schema can also be done via the UI * Update README.md * Update setup.js Co-authored-by: Matthew Sweeney <mail@msweeneydev.com> Co-authored-by: Joe Haddad <timer150@gmail.com>
1 parent f24aa41 commit 7d419f8

File tree

4 files changed

+126
-3
lines changed

4 files changed

+126
-3
lines changed

examples/with-graphql-faunadb/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,21 @@ By importing a `.gql` or `.graphql` schema into FaunaDB ([see our sample schema
1616

1717
You can start with this template [using `create-next-app`](#using-create-next-app) or by [downloading the repository manually](#download-manually).
1818

19-
To use a live FaunaDB database, create one and import this example's `schema.gql` file using the FaunaDB console. Create a client secret, then paste it into `next.config.js`.
19+
To use a live FaunaDB database, create a database at [dashboard.fauna.com](https://dashboard.fauna.com/) and generate a server token by going to the **Security** tab on the left and then click **New Key**. Give the new key a name and select the 'Server' Role. Copy the token since the setup script will ask for it. Do not use it in the frontend, it has superpowers which you don't want to give to your users.
20+
21+
The database can then be set up with the delivered setup by running:
22+
23+
```
24+
yarn setup
25+
```
26+
27+
This script will ask for the server token. Once you provide it with a valid token, this is what the script automatically does for you:
28+
29+
- **Import the GraphQL schema**, by importing a GraphQL schema in FaunaDB, FaunaDB automatically sets up collections and indexes to support your queries. This is now done for you with this script but can also be done from the [dashboard.fauna.com](https://dashboard.fauna.com/) UI by going to the GraphQL tab
30+
- **Create a role suitable for the Client**, FaunaDB has a security system that allows you to define which resources can be accessed for a specific token. That's how we limit our clients powers, feel free to look at the scripts/setup.js script to see how we make roles and tokens.
31+
- **Create a token for that role** which is printed, this is the token to be used in the frontend.
32+
33+
At the end, the newly generated client token will be printed and should be used to replace the '< GRAPHQL_SECRET >' placeholder in the next.config.js config.
2034

2135
### Using `create-next-app`
2236

examples/with-graphql-faunadb/next.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module.exports = {
88
| https://docs.fauna.com/fauna/current/security/
99
|--------------------------------------------------
1010
*/
11-
faunaDbSecret: 'fnADcnWRUcACE_6uDSw05MspruDdWKk88ZSmsm2a',
11+
faunaDbSecret: '< GRAPHQL_SECRET >',
1212
faunaDbGraphQlEndpoint: 'https://graphql.fauna.com/graphql',
1313
},
1414
}

examples/with-graphql-faunadb/package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55
"scripts": {
66
"dev": "next",
77
"build": "next build",
8-
"start": "next start"
8+
"start": "next start",
9+
"setup": "node ./scripts/setup.js"
910
},
1011
"dependencies": {
1112
"next": "latest",
1213
"react": "^16.10.2",
1314
"react-dom": "^16.10.2"
15+
},
16+
"devDependencies": {
17+
"faunadb": "2.11.1",
18+
"request": "2.88.0",
19+
"stream-to-promise": "2.2.0"
1420
}
1521
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// This script sets up the database to be used for this example application.
2+
// Look at the code to see what is behind the magic
3+
const faunadb = require('faunadb')
4+
const q = faunadb.query
5+
const request = require('request')
6+
const fs = require('fs')
7+
const streamToPromise = require('stream-to-promise')
8+
9+
const readline = require('readline').createInterface({
10+
input: process.stdin,
11+
output: process.stdout,
12+
})
13+
14+
// In order to set up a database, we need a server key, so let's ask the user for a key.
15+
readline.question(`Please provide the FaunaDB server key\n`, serverKey => {
16+
// A graphql schema can be imported in override or merge mode: 'https://docs.fauna.com/fauna/current/api/graphql/endpoints#import'
17+
const options = {
18+
model: 'merge',
19+
uri: 'https://graphql.fauna.com/import',
20+
headers: { Authorization: `Bearer ${serverKey}` },
21+
}
22+
const stream = fs.createReadStream('./schema.gql').pipe(request.post(options))
23+
24+
streamToPromise(stream)
25+
.then(res => {
26+
const readableResult = res.toString()
27+
if (readableResult.startsWith('Invalid authorization header')) {
28+
console.error('You need to provide a secret, closing. Try again')
29+
return readline.close()
30+
} else if (readableResult.startsWith('Invalid database secret')) {
31+
console.error(
32+
'The secret you have provided is not valid, closing. Try again'
33+
)
34+
return readline.close()
35+
} else if (readableResult.includes('success')) {
36+
console.log('1. Successfully imported schema')
37+
return readline.close()
38+
}
39+
})
40+
.catch(err => {
41+
console.error(err)
42+
console.error(`Could not import schema, closing`)
43+
})
44+
.then(res => {
45+
// The GraphQL schema is important, this means that we now have a GuestbookEntry Colleciton and an entries index.
46+
// Then we create a token that can only read and write to that index and collection
47+
var client = new faunadb.Client({ secret: serverKey })
48+
return client
49+
.query(
50+
q.CreateRole({
51+
name: 'GuestbookRole',
52+
privileges: [
53+
{
54+
resource: q.Collection('GuestbookEntry'),
55+
actions: { read: true, write: true },
56+
},
57+
{
58+
resource: q.Index('entries'),
59+
actions: { read: true },
60+
},
61+
],
62+
})
63+
)
64+
.then(res => {
65+
console.log(
66+
'2. Successfully created role to read and write guestbook entries'
67+
)
68+
})
69+
.catch(err => {
70+
if (err.toString().includes('instance already exists')) {
71+
console.log('2. Role already exists.')
72+
} else {
73+
throw err
74+
}
75+
})
76+
})
77+
.catch(err => {
78+
console.error(err)
79+
console.error(`Failed to create role, closing`)
80+
})
81+
.then(res => {
82+
// The GraphQL schema is important, this means that we now have a GuestbookEntry Colleciton and an entries index.
83+
// Then we create a token that can only read and write to that index and collection
84+
var client = new faunadb.Client({ secret: serverKey })
85+
return client
86+
.query(
87+
q.CreateKey({
88+
role: q.Role('GuestbookRole'),
89+
})
90+
)
91+
.then(res => {
92+
console.log('3. Created key to use in client')
93+
console.log(
94+
'Replace the < GRAPHQL_SECRET > placehold in next.config.js with:'
95+
)
96+
console.log(res.secret)
97+
})
98+
})
99+
.catch(err => {
100+
console.error(err)
101+
console.error(`Failed to create key, closing`)
102+
})
103+
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy