Giter Site home page Giter Site logo

fwitter's Introduction

A full introduction to this project can be found in the docs.

This project is an example of how to build a 'real-world' app with highly dynamic data in a serverless fashion using React hooks and FaunaDB. Since FaunaDB was developed by ex-Twitter engineers, a Twitter-like application felt like an appropriately sentimental choice, and we call this serverless baby ‘Fwitter’.

There is a first CSS-tricks article that describes the application in general, explains auth, data modeling and simple queries and brushes over the other features. More articles are coming on the Fauna blog and/or CSS Tricks.

It uses the Fauna Query Language (FQL) and starts with a frontend-only approach that directly accesses the serverless database FaunaDB for data storage, authentication, and authorization.

A few features are still missing and will be covered in future articles, including streaming, pagination, benchmarks, and a more advanced security model with short-lived tokens, JWT tokens, single sign-on (possibly using a service like Auth0), IP-based rate limiting (with Cloudflare workers), e-mail verification (with a service like SendGrid), and HttpOnly cookies.

Prerequisites

This app requires Node.js version 14 (LTS) or later.

Set up the project

This app was created with Create React App. To start using it we need to:

Install npm packages

npm install

Set up the database

To set up the project, go to the FaunaDB Dashboard and sign up.

Once you are in the dashboard, click on New Database, select Classic for the Region Group, fill in a name, and click Save.

You should now be on the "Overview" page of your new database. Next, to manipulate the database from within our setup scripts, we need a key. Click on the Security tab in the left sidebar, then click the New key button.

In the "New key" form, the current database should already be selected. For "Role", leave it as "Admin" and give it a name.

Next, click Save and copy the key secret displayed on the next page. It will not be displayed again.

You now have the option to place it in your environment variables (REACT_APP_LOCAL___ADMIN) via .env.local, we have provided an example file .env.local.example that you can rename. Although the .env.local file is gitignored, make sure not to push your admin key, this key is powerful and meant to stay private. The setup scripts will therefore also ask you the key if you did not place it in your environment vars so you could opt to paste them in then instead.

REACT_APP_LOCAL___ADMIN=<insert your admin key>

We have prepared a few scripts so that you only have to run the following commands to initialize your app, create all collections, and populate your database. The scripts will ask for the admin token that you have created and will give you further instructions.

// run setup, this will create all the resources in your database
// provide the admin key when the script asks for it. 
npm run setup

When this script has finished setting up everything you will receive a new key which will automatically be written in your .env.local file (or create this file if it doesn't exist yet from the example file). This key is the bootstrap key that has very tight permissions (it can only register and login) and will be used to bootstrap our application.

REACT_APP_LOCAL___BOOTSTRAP_FAUNADB_KEY=<insert faunadb bootstrap key>

Populate the database (optional)

We also provide a script that adds some data to the database (accounts, users, fweets, comments, likes, etc..) for you to play around with. It will use or ask for the same admin key.

npm run populate

Once you do, you will get four users to login with:

all with password: 'testtest'

If you do not see a lot on the feed of the user you logged in with, search for another user (type in a letter such as 'b' or 'a') and click the + sign to follow him/her.

Run the project

This project has been created with Create React App and therefore has the same familiar commands:

npm start

to start your application.

Update something in the setup

What if I am experimenting and want to update something? To update User Defined Functions or Roles you can just alter the definition and run npm run setup again. It will verify whether the role/function exists and override it.

One thing that can't be altered just like that are indexes (makes sense of course, they could contain quite some data). In order to just set up from scratch again you can run npm run destroy followed by npm run setup. Note, that since names such as collections and indexes are cached, you will have to wait +-60 secs but we can easily get around that by just removing and adding the complete database. In that case, we would remove our ADMIN key as well which would mean that we have to generate a new one each time. However, if we just create an admin key and use that to add (on setup) and remove (on destroy) a child database, than we can get around that inconvenience. We have provided you with that option. When you add the environment variable 'REACT_APP_LOCAL___CHILD_DB_NAME', the script will create a child database on npm run setup and destroy it on npm run destroy instead of removing all collections/indexes/functions.

fwitter's People

Contributors

cleve-fauna avatar dependabot-preview[bot] avatar dependabot[bot] avatar dihmeetree avatar fauna-brecht avatar fireridlle avatar lelouchb avatar n400 avatar rts-rob avatar steve-fauna avatar tbdsux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fwitter's Issues

Editing Fweets

How would I go about building an edit Fweet functionality?

Rate limiting

Thank you for the great example of rate-limiting. I have some thoughts.

As I understand it, it's not possible to protect Fauna DB misuse with any public key.
But it's perfectly possible to protect user-specific (secret token) data with FQL only.

So we have two DOS attack surfaces. Login/Register and public data rendering.

Login/Register can be only protected with some IP magic or with CAPTCHA.

Public data can not be protected with FQL only. Someone can read and read and read and we pay and pay and pay, or have to disable a service. For an application like Fwitter is, it makes only sense to lazy prerender tweets to serve them from CDN.

Please correct me if I am wrong. Thank you.

Wrong message for skipping/executing setup

Hi

I'm working through setup script and noted that fwitter uses

 await handleSetupError(
      client.query(If(Exists(Database(childDbName)), false, CreateDatabase({ name: childDbName }))),
      'database - create child database'
    )

https://github.com/fauna-brecht/fwitter/blob/master/scripts/setup.js#L58

The thing is that in case of existing database, the error handler get just false value from correctly resolved promise - so there is no error to catch as far as handler is concerned.

In effect, handler doesn't report "Skipping- instance already exists" but reports "[Executed]..." every time.

It should be just:

client.query(CreateDatabase({ name: childDbName }))

to report creating or skipping correctly.

Remove `Now` from index bindings

Now is not permitted within index bindings. There is disclaimer that the result will not be what is intended, but in fact using Now can cause a runtime error that prevents the index from ever completing.

// DISCLAIMER !!!!
// Now() should not be used in bindings since it does not provide correct results,
// Something I did not know at the time of writing.
// Instead please use either a created_at time you store on the document
// or an updated time instead. We'll update the app from the moment I find time to test
// an alternative approach.
txtime: Now(),

Fweets should have a created_at field that can be referred to in the index binding. This is also more correct anyway, since created_at timestamp is better to use than the latest updated time stamp.

Reporting a vulnerability

Hello!

I hope you are doing well!

We are a security research team. Our tool automatically detected a vulnerability in this repository. We want to disclose it responsibly. GitHub has a feature called Private vulnerability reporting, which enables security research to privately disclose a vulnerability. Unfortunately, it is not enabled for this repository.

Can you enable it, so that we can report it?

Thanks in advance!

PS: you can read about how to enable private vulnerability reporting here: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository

npm install fails with node 16

On macOS Big Sur clean install, I get:

npm ERR! In file included from ../src/binding.cpp:1:
npm ERR! In file included from ../../nan/nan.h:56:
npm ERR! In file included from /Users/savs/Library/Caches/node-gyp/16.0.0/include/node/node.h:63:
npm ERR! In file included from /Users/savs/Library/Caches/node-gyp/16.0.0/include/node/v8.h:30:
npm ERR! /Users/savs/Library/Caches/node-gyp/16.0.0/include/node/v8-internal.h:452:38: error: no template named 'remove_cv_t' in namespace 'std'; did you mean 'remove_cv'?
npm ERR!             !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
npm ERR!                                 ~~~~~^~~~~~~~~~~
npm ERR!                                      remove_cv
npm ERR! /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/type_traits:776:50: note: 'remove_cv' declared here
npm ERR! template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
npm ERR!                                                  ^
npm ERR! 1 error generated.
npm ERR! make: *** [Release/obj.target/binding/src/binding.o] Error 1
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: `make` failed with exit code: 2
npm ERR! gyp ERR! stack     at ChildProcess.onExit (/Users/savs/Development/fwitter/node_modules/node-gyp/lib/build.js:194:23)
npm ERR! gyp ERR! stack     at ChildProcess.emit (node:events:365:28)
npm ERR! gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
npm ERR! gyp ERR! System Darwin 20.4.0
npm ERR! gyp ERR! command "/usr/local/Cellar/node/16.0.0_1/bin/node" "/Users/savs/Development/fwitter/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
npm ERR! gyp ERR! cwd /Users/savs/Development/fwitter/node_modules/node-sass
npm ERR! gyp ERR! node -v v16.0.0
npm ERR! gyp ERR! node-gyp -v v7.1.2
npm ERR! gyp ERR! not ok
npm ERR! Build failed with error code: 1

Seems to be a problem with node 16 (see e.g. this stack overflow post) ... workaround is to downgrade to node 14:

brew unlink node
brew install node@14
brew link --overwrite node@14
npm install

Suggest updating README to highlight dependencies.

Unhandled Rejection Error

Getting the following error after following the steps in the README (using Firefox). Works in chrome.

image

Reporting a vulnerability

Hello!

I hope you are doing well!

We are a security research team. Our tool automatically detected a vulnerability in this repository. We want to disclose it responsibly. GitHub has a feature called Private vulnerability reporting, which enables security research to privately disclose a vulnerability. Unfortunately, it is not enabled for this repository.

Can you enable it, so that we can report it?

Thanks in advance!

PS: you can read about how to enable private vulnerability reporting here: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository

GraphQL?

Any chance this app / tutorial will one day demonstrate importing a GraphQL schema and using GraphQL in the app? 👯

(I have loved following this to learn more FQL but would also love to see a sample GraphQL schema and how FQL might handle more complex indexing / functions in the client)

Any Roadmap?

Would be great to see this demo evolving frequently, it has a lot of potential.

Any plans to add these features "streaming, pagination, benchmarks, and a more advanced security model..."

Code isn't aware of region groups

The documentation should either specify that the database needs to be created in Classic or the code needs to be refactored to be region group aware. It probably should be part of the setup process (or auto determined by the client somehow by interrogating the key). Thoughts on approach? I could take a stab at fixing.

error when build

> react-scripts build

Creating an optimized production build...
Failed to compile.

Can't find self.__WB_MANIFEST in your SW source.


npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `react-scripts build`
npm ERR! Exit status 1

npm start working fine. I'm using node v12.22.1

Awesome As (No Issue, Just Praise)

Just some positive words of thanks in case the OG devs visit here. This work is greatly appreciated. To be honest I don't really understand the syntax of React and the configuration but I understand the relationships between parts and I can see how efficient Fauna is at registering changes in the front-end to the back-end. This demo is really kick-ass. 🤙

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.