From 0 to "Hello World"
=======================

Goal:

The purpose of this tutorial is to install Walnut and be able to launch a simple "Hello World" app.

Pre-requisites:

* You have compatible server hardware
  * Daplie Server
  * EspressoBin
  * Raspberry Pi
  * MacBook
  * (pretty much anything, actually)
* You have compatible software
  * Linux of any sort that uses systemd
  * macOS using launchd
* You own a domain
  * through Daplie Domains
  * or you understand domains and DNS and all that stuff
* Install bower `npm install -g bower`

Choose a domain
---------------

For the purpose of this instruction we'll assume that your domain is `foo.com`,
but you can use, say, `johndoe.daplie.me` for testing through Daplie Domains.

Anyway, go ahead and set the bash variable `$my_domain` for the purposes of the
rest of this tutorial:

```
my_domain=foo.com
```

You can purchase a domain with daplie tools

```bash
npm install -g git+https://git.daplie.com/Daplie/daplie-tools.git

daplie domains:search -n $my_domain
```

Subdomains
----------

Auth will be loaded with the following domains

```
provider.foo.com
api.provider.foo.com
```

The Hello World app will be loaded with the following domains

```
foo.com
www.foo.com
api.foo.com
assets.foo.com
```

The domains can be setup through the Daplie Desktop App or with daplie-tools

Replace `foodevice` with whatever you like to call this device

```bash
# hostname
my_device=foodevice

# curl https://api.oauth3.org/api/tunnel@oauth3.org/checkip
# READ THIS: localhost is being used as an example.
# Your IP address should be public facing (i.e. port-forwarding is enabled on your router).
# If it isn't, then you need something like goldilocks providing a tunnel.
my_address=127.0.0.1

# set device address and attach primary domain
daplie devices:attach -d $my_device -n $my_domain -a $my_address

# attach all other domains with same device/address
daplie devices:attach -d $my_device -n provider.$my_domain
daplie devices:attach -d $my_device -n api.provider.$my_domain
daplie devices:attach -d $my_device -n www.$my_domain
daplie devices:attach -d $my_device -n api.$my_domain
daplie devices:attach -d $my_device -n assets.$my_domain
daplie devices:attach -d $my_device -n cloud.$my_domain
daplie devices:attach -d $my_device -n api.cloud.$my_domain
```

Goldilocks Configuration
------------------------

Walnut must sit behind a proxy that properly terminates https and sets the `X-Forwarded-Proto` header.

Goldilocks can do this, as well as manage daplie domains, tunneling, etc.

```bash
curl https://git.daplie.com/Daplie/daplie-snippets/raw/master/install.sh | bash

daplie-install-goldilocks
```


Example `/etc/goldilocks/goldilocks.yml`:
```yml
tls:
  email: user@mailservice.com
  servernames:
    - foo.com
    - www.foo.com
    - api.foo.com
    - assets.foo.com
    - cloud.foo.com
    - api.cloud.foo.com
    - provider.foo.com
    - api.provider.foo.com

http:
  trust_proxy: true
  modules:
    - name: proxy
      domains:
        - '*'
      address: '127.0.0.1:3000'
```

Basic Walnut Install
--------------------

```bash
curl https://git.daplie.com/Daplie/daplie-snippets/raw/master/install.sh | bash

daplie-install-walnut
```

You could also, of course, try installing from the repository directly
(especially if you have goldilocks or some similar already installed)

```bash
mkdir -p /srv/walnut/
git clone https://git.daplie.com/Daplie/walnut.js.git /srv/walnut/core
pushd /srv/walnut/core
  git checkout v1
popd
bash /srv/walnut/core/install-helper.sh
```

Initial Configuration
-------------

Once installed and started you can visit <https://localhost.daplie.me:3000> to configure the primary domain.

You could also do this manually via curl:

```bash
curl -X POST http://api.localhost.daplie.me:3000/api/walnut@daplie.com/init \
  -H 'X-Forwarded-Proto: https' \
  -H 'Content-Type: application/json' \
  -d '{ "domain": "'$my_domain'" }'
```

Resetting the Initialization
----------------------------

Once you run the app the initialization files will appear in these locations

```
/srv/walnut/var/walnut+config@daplie.com.sqlite3
/srv/walnut/config/foo.com.json
```

Deleting those files and restarting walnut will reset it to its bootstrap state.

Reset Permissions
-----------------

Since the app store and package manager are not built yet,
you should also change the permissions on the walnut directory for the purposes of this tutorial:

```bash
sudo chown -R $(whoami) /srv/walnut/
sudo chmod -R +s /srv/walnut/
```

Install OAuth3 API Package
--------------

We need to have a local login system.

For the APIs for that we'll install the `issuer@oauth3.org` API package and enable it for `api.provider.example.com`:

```bash
# API packaged for walnut
git clone https://git.daplie.com/OAuth3/issuer_oauth3.org.git /srv/walnut/packages/rest/issuer@oauth3.org
pushd /srv/walnut/packages/rest/issuer@oauth3.org/
    git checkout v1.2
    npm install
popd

# Give permission for this package to provider.example.com
# the api. prefix is omitted because it is always assumed for APIs
echo "issuer@oauth3.org" >> /srv/walnut/packages/client-api-grants/provider.$my_domain
```

*NOTE*: Currently there are some hard-coded values that need to be changed out (TODO use `getSiteConfig()`).
`vim /srv/walnut/packages/rest/issuer@oauth3.org/lib/provide-oauth3.js` and search for the email stuff and change it.


For the user interface for that we'll install the `issuer@oauth3.org` site package and enable it

```bash
# Frontend
git clone https://git.daplie.com/OAuth3/org.oauth3.git /srv/walnut/packages/pages/issuer@oauth3.org
pushd /srv/walnut/packages/pages/issuer@oauth3.org
  bash ./install.sh
popd

# Tell Walnut to load this site package when provider.example.com is requested
echo "issuer@oauth3.org" >> /srv/walnut/var/sites/provider.$my_domain
```

OAuth3 Secrets
--------------

OAuth3 is currently configured to use mailgun for sending verification emails.
It is intended to provide a way to use various mail services in the future,
just bear with us for the time being (or open a Merge Request).

```bash
mkdir -p /srv/walnut/var/provider.$my_domain
vim /srv/walnut/var/provider.$my_domain/config.json
```

```json
{ "mailgun.org": {
    "apiKey": "key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  , "auth": {
      "user": "robtherobot@example.com"
    , "pass": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    , "api_key": "key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    , "domain": "example.com"
    }
  }
, "issuer@oauth3.org": {
    "mailer": {
      "from": "login@example.com"
    , "subject": "Login code request"
    , "text": ":code\n\nis your login code"
    }
  }
}
```

Install the 'hello@example.com' package
---------------------

```bash
git clone https://git.daplie.com/Daplie/com.example.hello.git /srv/walnut/packages/rest/hello@example.com

echo "hello@example.com" >> /srv/walnut/packages/client-api-grants/provider.$my_domain
```

What it should look like:

```
/srv/walnut/packages/rest/hello@example.com/
  package.json
  api.js
  models.js
  rest.js

/srv/walnut/packages/client-api-grants/provider.foo.com
  '''
  issuer@oauth3.org
  hello@example.com
  '''
```

Setup the Seed App (front-end)
------------------------

Get the Seed App

```bash
pushd /srv/walnut/packages/pages/

git clone https://git.daplie.com/Daplie/seed_example.com.git --branch v1 seed@example.com

pushd seed@example.com/
  git clone https://git.daplie.com/OAuth3/oauth3.js.git --branch v1.1 assets/oauth3.org

  mkdir -p .well-known
  ln -sf  ../assets/oauth3.org/.well-known/oauth3 .well-known/oauth3
popd

echo "seed@example.com" >> /srv/walnut/var/sites/$my_domain

popd
```

You will need to change the authenication provider/issuer URL from `oauth3.org` to the domain you've selected (i.e. `provider.example.com`)

```bash
vim /srv/walnut/packages/pages/seed@example.com/js/config.js
```

```js
{ "azp@oauth3.org": { issuer_uri: 'provider.example.com', client_uri: 'example.com' } }
```

See Hello World
---------------

Now visit your site (i.e. https://example.com) and you will be able to login
and access the hello world data.
