diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..61a7393 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,45 @@ +# This file excludes paths from the Docker build context. +# +# By default, Docker's build context includes all files (and folders) in the +# current directory. Even if a file isn't copied into the container it is still sent to +# the Docker daemon. +# +# There are multiple reasons to exclude files from the build context: +# +# 1. Prevent nested folders from being copied into the container (ex: exclude +# /assets/node_modules when copying /assets) +# 2. Reduce the size of the build context and improve build time (ex. /build, /deps, /doc) +# 3. Avoid sending files containing sensitive information +# +# More information on using .dockerignore is available here: +# https://docs.docker.com/engine/reference/builder/#dockerignore-file + +.dockerignore + +# Ignore git, but keep git HEAD and refs to access current commit hash if needed: +# +# $ cat .git/HEAD | awk '{print ".git/"$2}' | xargs cat +# d0b8727759e1e0e7aa3d41707d12376e373d5ecc +.git +!.git/HEAD +!.git/refs + +# Common development/test artifacts +/cover/ +/doc/ +/test/ +/tmp/ +.elixir_ls + +# Mix artifacts +/_build/ +/deps/ +*.ez + +# Generated on crash by the VM +erl_crash.dump + +# Static artifacts - These should be fetched and built inside the Docker image +/assets/node_modules/ +/priv/static/assets/ +/priv/static/cache_manifest.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 372c425..932a171 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,22 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} MIX_ENV: test - AUTH_API_KEY: 2PzB7PPnpuLsbWmWtXpGyI+kfSQSQ1zUW2Atz/+8PdZuSEJzHgzGnJWV35nTKRwx/authdev.herokuapp.com + AUTH_API_KEY: 2PzB7PPnpuLsbWmWtXpGyI+kfSQSQ1zUW2Atz/+8PdZuSEJzHgzGnJWV35nTKRwx/authdemo.fly.dev - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 + + # Continuous Deployment to Fly.io + # https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ + deploy: + name: Deploy app + runs-on: ubuntu-latest + needs: build + # https://stackoverflow.com/questions/58139406/only-run-job-on-specific-branch-with-github-actions + if: github.ref == 'refs/heads/main' + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + steps: + - uses: actions/checkout@v2 + - uses: superfly/flyctl-actions@1.1 + with: + args: "deploy" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a26dc2e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,90 @@ +# Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian instead of +# Alpine to avoid DNS resolution issues in production. +# +# https://hub.docker.com/r/hexpm/elixir/tags?page=1&name=ubuntu +# https://hub.docker.com/_/ubuntu?tab=tags +# +# +# This file is based on these images: +# +# - https://hub.docker.com/r/hexpm/elixir/tags - for the build image +# - https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye-20220801-slim - for the release image +# - https://pkgs.org/ - resource for finding needed packages +# - Ex: hexpm/elixir:1.14.1-erlang-25.1.1-debian-bullseye-20220801-slim +# +ARG ELIXIR_VERSION=1.14.1 +ARG OTP_VERSION=25.1.1 +ARG DEBIAN_VERSION=bullseye-20220801-slim + +ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}" +ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}" + +FROM ${BUILDER_IMAGE} as builder + +# install build dependencies +RUN apt-get update -y && apt-get install -y build-essential git \ + && apt-get clean && rm -f /var/lib/apt/lists/*_* + +# prepare build dir +WORKDIR /app + +# install hex + rebar +RUN mix local.hex --force && \ + mix local.rebar --force + +# set build ENV +ENV MIX_ENV="prod" + +# install mix dependencies +COPY mix.exs mix.lock ./ +RUN mix deps.get --only $MIX_ENV +RUN mkdir config + +# copy compile-time config files before we compile dependencies +# to ensure any relevant config change will trigger the dependencies +# to be re-compiled. +COPY config/config.exs config/${MIX_ENV}.exs config/ +RUN mix deps.compile + +COPY priv priv + +COPY lib lib + +# Compile the release +RUN mix compile + +# Changes to config/runtime.exs don't require recompiling the code +COPY config/runtime.exs config/ + +COPY rel rel +RUN mix release + +# start a new build stage so that the final image will only contain +# the compiled release and other runtime necessities +FROM ${RUNNER_IMAGE} + +RUN apt-get update -y && apt-get install -y libstdc++6 openssl libncurses5 locales \ + && apt-get clean && rm -f /var/lib/apt/lists/*_* + +# Set the locale +RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen + +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +WORKDIR "/app" +RUN chown nobody /app + +# set runner ENV +ENV MIX_ENV="prod" + +# Only copy the final release from the build stage +COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/app ./ + +USER nobody + +CMD ["/app/bin/server"] +# Appended by flyctl +ENV ECTO_IPV6 true +ENV ERL_AFLAGS "-proto_dist inet6_tcp" diff --git a/Procfile b/Procfile deleted file mode 100644 index a8f0694..0000000 --- a/Procfile +++ /dev/null @@ -1 +0,0 @@ -web: mix phx.digest && mix phx.server \ No newline at end of file diff --git a/README.md b/README.md index 925280b..4e40c17 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ in your Phoenix App! ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/dwyl/auth_plug_example/Elixir%20CI?label=build&style=flat-square) [![codecov.io](https://img.shields.io/codecov/c/github/dwyl/auth_plug_example/master.svg?style=flat-square)](http://codecov.io/github/dwyl/auth_plug_example?branch=master) [![Hex.pm](https://img.shields.io/hexpm/v/auth_plug?color=brightgreen&style=flat-square)](https://hex.pm/packages/auth_plug) -[![Libraries.io dependency status](https://img.shields.io/librariesio/release/hex/auth_plug?logoColor=brightgreen&style=flat-square)](https://github.com/dwyl/auth_plug/blob/master/mix.exs) [![HitCount](http://hits.dwyl.com/dwyl/auth_plug_example.svg)](http://hits.dwyl.com/dwyl/auth_plug_example) +[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/dwyl/auth_plug/issues)
@@ -33,12 +33,16 @@ and showcase a protected route. Before you attempt to use the **`auth_plug`**, try the Heroku example version so you know what to expect: -https://auth-plug-example.herokuapp.com/admin -![wake-sleeping-heroku-app](http://auth-plug-example.herokuapp.com/ping) +https://auth-plug.fly.dev/admin You will be redirected to: -![auth_plug_example](https://user-images.githubusercontent.com/194400/80765920-154eb600-8b3c-11ea-90d4-a64224d31a5b.png) +![auth_demo](https://user-images.githubusercontent.com/194400/202489883-16d727f4-8f18-4fba-9e27-00ea01329482.png) + +Once you have logged in, you will be redirected back: + + +![auth_plug_example-logged-in](https://user-images.githubusercontent.com/194400/202489177-47c53d17-d4e4-44eb-a923-c64e14ad214c.png) @@ -56,9 +60,10 @@ to add Auth to _any_ app in less than 2 minutes! ### 1. Create New Phoenix App -``` +```sh mix phx.new app --no-ecto --no-webpack ``` + When asked if you want to `Fetch and install dependencies? [Yn]` Type Y followed by the Enter key. @@ -84,7 +89,7 @@ and locate the `defp deps do` section. Add the line: ``` -{:auth_plug, "~> 1.2.1"} +{:auth_plug, "~> 1.4"} ``` > E.g: @@ -105,7 +110,7 @@ Open the `lib/app_web/router.ex` file and locate the section: Immediately below this add the following lines of code: ```elixir - pipeline :auth, do: plug(AuthPlug, %{auth_url: "https://dwylauth.herokuapp.com"}) + pipeline :auth, do: plug(AuthPlug) scope "/", AppWeb do pipe_through :browser @@ -183,11 +188,12 @@ And paste the following code into it: ### 6. Get and Set the `AUTH_API_KEY` Environment Variable -Visit: https://dwylauth.herokuapp.com +Visit: +[authdemo.fly.dev](https://authdemo.fly.dev/apps/new) and create a New App: -![dwyl-auth-app-api-key-setup](https://user-images.githubusercontent.com/194400/93143513-0712c800-f6e0-11ea-9020-c253805d66df.gif) +![dwyl-auth-app-api-key-setup](https://user-images.githubusercontent.com/194400/202491060-6c2d015b-1313-4f94-8a8c-cdb52bd8aa5f.png) Save the key as an environment variable named `AUTH_API_KEY`. @@ -211,7 +217,7 @@ Now open your web browser to: http://localhost:4000/admin Given that you are not yet authenticated, your request will be redirected to -https://dwylauth.herokuapp.com/?referer=http://localhost:4000/admin&auth_client_id=etc +https://authdemo.fly.dev/?referer=http://localhost:4000/admin&auth_client_id=etc Once you have successfully authenticated with your GitHub or Google account, you will be redirected back to `localhost:4000/admin` diff --git a/config/config.exs b/config/config.exs index 1aa25b0..ed2bed9 100644 --- a/config/config.exs +++ b/config/config.exs @@ -5,7 +5,7 @@ # is restricted to this project. # General application configuration -use Mix.Config +import Mix.Config # Configures the endpoint config :app, AppWeb.Endpoint, @@ -29,4 +29,4 @@ config :phoenix, :json_library, Jason import_config "#{Mix.env()}.exs" config :auth_plug, - api_key: System.get_env("AUTH_API_KEY") \ No newline at end of file + api_key: System.get_env("AUTH_API_KEY") diff --git a/config/dev.exs b/config/dev.exs index 5c91a94..63affcf 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Mix.Config # For development, we disable any cache and enable # debugging and code reloading. diff --git a/config/prod.exs b/config/prod.exs index 8a025d5..493e19e 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Mix.Config # For production, don't forget to configure the url host # to something meaningful, Phoenix uses this information diff --git a/config/prod.secret.exs b/config/prod.secret.exs index ed6aad9..619956a 100644 --- a/config/prod.secret.exs +++ b/config/prod.secret.exs @@ -2,7 +2,7 @@ # from environment variables. You can also hardcode secrets, # although such is generally not recommended and you have to # remember to add this file to your .gitignore. -use Mix.Config +import Mix.Config secret_key_base = System.get_env("SECRET_KEY_BASE") || diff --git a/config/runtime.exs b/config/runtime.exs new file mode 100644 index 0000000..f7a8600 --- /dev/null +++ b/config/runtime.exs @@ -0,0 +1,58 @@ +import Config + +# config/runtime.exs is executed for all environments, including +# during releases. It is executed after compilation and before the +# system starts, so it is typically used to load production configuration +# and secrets from environment variables or elsewhere. Do not define +# any compile-time configuration in here, as it won't be applied. +# The block below contains prod specific runtime configuration. + +# ## Using releases +# +# If you use `mix release`, you need to explicitly enable the server +# by passing the PHX_SERVER=true when you start it: +# +# PHX_SERVER=true bin/app start +# +# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server` +# script that automatically sets the env var above. +if System.get_env("PHX_SERVER") do + config :app, AppWeb.Endpoint, server: true +end + +if config_env() == :prod do + + maybe_ipv6 = if System.get_env("ECTO_IPV6"), do: [:inet6], else: [] + + config :app, App.Repo, + # ssl: true, + pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"), + socket_options: maybe_ipv6 + + # The secret key base is used to sign/encrypt cookies and other secrets. + # A default value is used in config/dev.exs and config/test.exs but you + # want to use a different value for prod and you most likely don't want + # to check this value into version control, so we use an environment + # variable instead. + secret_key_base = + System.get_env("SECRET_KEY_BASE") || + raise """ + environment variable SECRET_KEY_BASE is missing. + You can generate one by calling: mix phx.gen.secret + """ + + host = System.get_env("PHX_HOST") || "example.com" + port = String.to_integer(System.get_env("PORT") || "4000") + + config :app, AppWeb.Endpoint, + url: [host: host, port: 443, scheme: "https"], + http: [ + # Enable IPv6 and bind on all interfaces. + # Set it to {0, 0, 0, 0, 0, 0, 0, 1} for local network only access. + # See the documentation on https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html + # for details about using IPv6 vs IPv4 and loopback vs public addresses. + ip: {0, 0, 0, 0, 0, 0, 0, 0}, + port: port + ], + secret_key_base: secret_key_base +end diff --git a/config/test.exs b/config/test.exs index aed6522..9fba557 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,4 +1,4 @@ -use Mix.Config +import Mix.Config # We don't run a server during test. If one is required, # you can enable the server option below. @@ -10,4 +10,4 @@ config :app, AppWeb.Endpoint, config :logger, level: :warn config :auth_plug, - httpoison_mock: true \ No newline at end of file + httpoison_mock: true diff --git a/coveralls.json b/coveralls.json index 14f1ab6..a49d848 100644 --- a/coveralls.json +++ b/coveralls.json @@ -7,6 +7,7 @@ "lib/app.ex", "lib/app_web.ex", "lib/app/application.ex", - "lib/app_web/views/error_helpers.ex" + "lib/app_web/views/error_helpers.ex", + "lib/app_web/channels/user_socket.ex" ] } diff --git a/elixir_buildpack.config b/elixir_buildpack.config deleted file mode 100644 index e85fb2f..0000000 --- a/elixir_buildpack.config +++ /dev/null @@ -1,8 +0,0 @@ -# Elixir version -elixir_version=1.12.3 - -# Erlang version -# available versions https://github.com/HashNuke/heroku-buildpack-elixir-otp-builds/blob/master/otp-versions -erlang_version=23.3.2 - -# always_rebuild=true diff --git a/fly.toml b/fly.toml new file mode 100644 index 0000000..4b97b2e --- /dev/null +++ b/fly.toml @@ -0,0 +1,40 @@ +# fly.toml file generated for auth-plug on 2022-11-17T15:15:15Z + +app = "auth-plug" +kill_signal = "SIGTERM" +kill_timeout = 5 +processes = [] + +[env] + PHX_HOST = "auth-plug.fly.dev" + PORT = "8080" + +[experimental] + allowed_public_ports = [] + auto_rollback = true + +[[services]] + http_checks = [] + internal_port = 8080 + processes = ["app"] + protocol = "tcp" + script_checks = [] + [services.concurrency] + hard_limit = 25 + soft_limit = 20 + type = "connections" + + [[services.ports]] + force_https = true + handlers = ["http"] + port = 80 + + [[services.ports]] + handlers = ["tls", "http"] + port = 443 + + [[services.tcp_checks]] + grace_period = "1s" + interval = "15s" + restart_limit = 0 + timeout = "2s" diff --git a/lib/app_web/controllers/page_controller.ex b/lib/app_web/controllers/page_controller.ex index 8f10da5..877d477 100644 --- a/lib/app_web/controllers/page_controller.ex +++ b/lib/app_web/controllers/page_controller.ex @@ -15,10 +15,6 @@ defmodule AppWeb.PageController do render(conn, "optional.html", auth_url: auth_url) end - def ping(conn, params) do - Ping.render_pixel(conn, params) - end - def logout(conn, _params) do conn |> AuthPlug.logout() diff --git a/lib/app_web/router.ex b/lib/app_web/router.ex index 735f5a1..b06e8c8 100644 --- a/lib/app_web/router.ex +++ b/lib/app_web/router.ex @@ -16,7 +16,6 @@ defmodule AppWeb.Router do pipe_through :authoptional get "/", PageController, :index get "/optional", PageController, :optional - get "/ping", PageController, :ping get "/logout", PageController, :logout end diff --git a/mix.exs b/mix.exs index 52e9676..7fbbbbf 100644 --- a/mix.exs +++ b/mix.exs @@ -4,10 +4,10 @@ defmodule App.MixProject do def project do [ app: :app, - version: "1.4.6", + version: "1.4.7", elixir: "~> 1.12", elixirc_paths: elixirc_paths(Mix.env()), - compilers: [:phoenix, :gettext] ++ Mix.compilers(), + compilers: [:phoenix] ++ Mix.compilers(), start_permanent: Mix.env() == :prod, aliases: aliases(), deps: deps(), @@ -35,18 +35,16 @@ defmodule App.MixProject do # Specifies project dependencies: defp deps do [ - {:phoenix, "~> 1.6.2"}, + {:phoenix, "~> 1.6.14"}, {:phoenix_pubsub, "~> 2.1.1"}, - {:phoenix_html, "~> 3.0"}, - {:phoenix_live_reload, "~> 1.2", only: :dev}, - {:gettext, "~> 0.18"}, - {:jason, "~> 1.2"}, + {:phoenix_html, "~> 3.2"}, + {:phoenix_live_reload, "~> 1.3", only: :dev}, + {:gettext, "~> 0.20"}, + {:jason, "~> 1.4"}, {:plug_cowboy, "~> 2.5"}, # github.com/dwyl/auth_plug {:auth_plug, "~> 1.5.0"}, - # wake up Heroku app - {:ping, "~> 1.1.0"}, # Check test coverage: https://github.com/parroty/excoveralls {:excoveralls, "~> 0.15.0", only: :test} diff --git a/mix.lock b/mix.lock index c301b81..1787cbd 100644 --- a/mix.lock +++ b/mix.lock @@ -25,8 +25,7 @@ "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, "phoenix_template": {:hex, :phoenix_template, "1.0.0", "c57bc5044f25f007dc86ab21895688c098a9f846a8dda6bc40e2d0ddc146e38f", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "1b066f99a26fd22064c12b2600a9a6e56700f591bf7b20b418054ea38b4d4357"}, "phoenix_view": {:hex, :phoenix_view, "2.0.1", "a653e3d9d944aace0a064e4a13ad473ffa68f7bc4ca42dbf83cc1d464f1fb295", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "6c358e2cefc5f341c728914b867c556bbfd239fed9e881bac257d70cb2b8a6f6"}, - "ping": {:hex, :ping, "1.1.0", "088a2e3356dc2a0f4b4b6b1dd50b08e108f31b0ea8058f20e621e0de27281415", [:mix], [{:plug, "~> 1.12.1", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "e05403a9fc8878e17e4b206fdaa77465c6b7fc4b9cc4dc3179dd3a93f39644b3"}, - "plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"}, + "plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"}, "plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"}, "plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, diff --git a/rel/overlays/bin/server b/rel/overlays/bin/server new file mode 100755 index 0000000..d7f7150 --- /dev/null +++ b/rel/overlays/bin/server @@ -0,0 +1,3 @@ +#!/bin/sh +cd -P -- "$(dirname -- "$0")" +PHX_SERVER=true exec ./app start diff --git a/rel/overlays/bin/server.bat b/rel/overlays/bin/server.bat new file mode 100755 index 0000000..d3cc94c --- /dev/null +++ b/rel/overlays/bin/server.bat @@ -0,0 +1,2 @@ +set PHX_SERVER=true +call "%~dp0\app" start diff --git a/test/app_web/controllers/page_controller_test.exs b/test/app_web/controllers/page_controller_test.exs index 422f8a2..ff47a9c 100644 --- a/test/app_web/controllers/page_controller_test.exs +++ b/test/app_web/controllers/page_controller_test.exs @@ -42,13 +42,6 @@ defmodule AppWeb.PageControllerTest do assert html_response(conn, 200) =~ "Welcome Alex" end - test "GET /ping (GIF) renders 1x1 pixel", %{conn: conn} do - conn = get(conn, "/ping") - assert conn.status == 200 - assert conn.state == :sent - assert conn.resp_body =~ <<71, 73, 70, 56, 57>> - end - test "get /logout with valid JWT", %{conn: conn} do data = %{email: "alex@dwyl.com", givenName: "Alexander", picture: "this", auth_provider: "GitHub", sid: 1}