|
| 1 | +# Guest book |
| 2 | + |
| 3 | +Sign a guestbook. Signatures done on the guestbook are stored in a Firebase server. The code for the server is included in the `/server` folder of this repo. It also implements a few security checks to ensure that the requests that arrive to the server are legitimate. |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +Check out the [related tutorial](https://decentraland.org/blog/tutorials/servers-part-2/)! |
| 8 | + |
| 9 | +This scene shows you: |
| 10 | + |
| 11 | +- How to send HTTP requests to an API to store data in a permanent place, so others can then retrieve changes |
| 12 | +- How to set up a server on Firebase that uses the Firestore database |
| 13 | +- How to display a custom UI |
| 14 | +- How to parse a JSON response from an API call |
| 15 | +- How to parse a string so that it fits a maximum line length and maximum number of lines |
| 16 | +- How to fetch the player's UserId |
| 17 | + |
| 18 | + |
| 19 | +Every time the book is opened, a request is sent to a RESFful API that this server exposes, to fetch all existing signatures. When a new signature is made, another request is sent to that API, including the player's name and id, to add to the database. |
| 20 | + |
| 21 | +## Try it out |
| 22 | + |
| 23 | +**Previewing the scene** |
| 24 | + |
| 25 | +1. Download this full repository from [sdk7-goerli-plaza](https://github.com/decentraland/sdk7-goerli-plaza/tree/main), including this and several other example scenes on SDK7. |
| 26 | + |
| 27 | +2. Install the [Decentraland Editor](https://docs.decentraland.org/creator/development-guide/sdk7/editor/) |
| 28 | + |
| 29 | +3. Open a Visual Studio Code window on `scene` directory. Not on the root folder of the whole repo, but instead on this sub-folder that belongs to the scene. |
| 30 | + |
| 31 | +4. Open the Decentraland Editor tab, and press **Run Scene** |
| 32 | + |
| 33 | +Alternatively, you can use the command line. Inside `scene` directory run: |
| 34 | + |
| 35 | +``` |
| 36 | +npm run start |
| 37 | +``` |
| 38 | + |
| 39 | +**Setting up the server** |
| 40 | + |
| 41 | +The scene is set up to make use of an existing server. To launch your own server, we recommend you deploy what's in the `server` folder to your own Firebase account, following the steps in [this tutorial](https://decentraland.org/blog/tutorials/servers-part-2/). |
| 42 | + |
| 43 | +**Scene Usage** |
| 44 | + |
| 45 | +Click on the guestbook to open the UI and fetch all the signatures on the book. You can flip through the pages by clicking the arrows on the sides. If you click the sign button, your user ID will be fetched and added to the list of signatures. If you run this on preview, you will be using the randomly generated `guest` UI used by preview. |
| 46 | + |
| 47 | +Since you're running the scene locally on localhost, the validations that relate to the request's origin and on querying the catalyst servers are turned off. Turn them on with the `TESTS_ENABLED` flag, on `securityChecks.ts` in the server folder. Notice that once that's enabled your requests from localhost will no longer pass the validations. |
| 48 | + |
| 49 | +By copying the `security` folder in `server`, you can use the same set of security validations on any request that was originated with `signedFetch()` in a Decentraland scene. |
| 50 | + |
| 51 | +Simply run: |
| 52 | + |
| 53 | +```ts |
| 54 | +await runChecks(req) |
| 55 | +``` |
| 56 | + |
| 57 | +Or add a set of coordinates to also validate the request's origin on the map: |
| 58 | + |
| 59 | +```ts |
| 60 | +await runChecks(req, VALID_PARCEL) |
| 61 | +``` |
| 62 | + |
| 63 | +## More About Validating Player Authenticity |
| 64 | + |
| 65 | +On the scene: |
| 66 | + |
| 67 | +- Send requests with `signedFetch`, to include headers with an ephemeral key signature in the request. |
| 68 | + |
| 69 | +On the server: |
| 70 | + |
| 71 | +- Check that the origin of the request, to ensure it's from a Decentraland domain |
| 72 | +- Filter out malicious IPs that were manually identified |
| 73 | +- Check that the headers included in the `signedFetch` are properly signed, ensuring also that the timestamp in the signature is also recent and that the ephemeral key corresponds to the player's address. |
| 74 | +- Query the catalyst server that the player claims to be in, and ensure that the player is truly there. |
| 75 | +- Check that the player's location when sending the request is at a specific parcel, or within a margin or error of that. |
| 76 | + |
| 77 | +These checks together ensure that a request needs to come from inside decentraland, from a player in a deployed scene within the specified coordinates. |
| 78 | + |
| 79 | +Through all of these checks, you can make it very hard for anyone who might want to take advantage of your scene. These security measures are especially valuable in scenes that give away tokens, or where there's some kind of monetary incentive for cheating. |
| 80 | + |
| 81 | +### About the ephemeral key |
| 82 | + |
| 83 | +When players log into decentraland, they sign a message using Metamask or their preferred web3 client. This signature is used to generate an ephemeral wallet that exists during that session, this address can be traced back to the player's original address. The advantage is that it can be used by the Decentraland explorer to sign messages behind the curtains, without requesting that the player manually signs every request. |
| 84 | + |
| 85 | +When you use the `signedFetch()` function in a scene, you're sending additional metadata in the request's headers, that includes a signed message encrypted with the ephemeral key. This signed message includes a timestamp, the player's position on the map, the player's actual address, and the contents of the request itself. |
| 86 | + |
| 87 | +### Configurable properties |
| 88 | + |
| 89 | +The following properties can be configured on `securityChecks.ts`: |
| 90 | + |
| 91 | +- `TESTS_ENABLED`: If true, requests from localhost are allowed. If false, the server also enforces that the requests come from a decentraland domain, and validates with a catalyst server that the player is currently there. |
| 92 | + |
| 93 | +- `MARGIN_OF_ERROR`: Make the location checks more or less permissive. A margin or error of 2 will allow locations at + - 2 parcels of distance on either axis from the indicated location. |
| 94 | + |
| 95 | +- `denyListedIPS`: Add any IPs to this list that you want to block from making any requests. |
| 96 | + |
| 97 | +## Copyright info |
| 98 | + |
| 99 | +This scene is protected with a standard Apache 2 licence. See the terms and conditions in the [LICENSE](/LICENSE) file. |
0 commit comments