Code Monkey home page Code Monkey logo

console's Introduction

Console

Code that powers the official Helium Console.

Development and Contribution

Any and all contributions from the community are encouraged.

  • Guidelines for how to contribute to this repository are here.
  • Discussion about the development and usage of the Helium Console takes place in the official Helium Discord Server, specifically in the #console channel. Join us!
  • To post feature requests or see a list of current issues please go here.

Common setup steps for Docker

cp templates/.env .env
cp templates/.env-router .env-router
  • Populate your newly copied .env file and .env-router file

Option 1: Running Console+Router with prebuilt Console image

cp templates/docker-compose-quay.yaml docker-compose.yaml
cp templates/nginx-default.conf nginx.conf
  • Get a certificate (https://certbot.eff.org/instructions)
  • Update nginx.conf with cert and key information
  • In .env, set SOCKET_CHECK_ORIGIN to your host domain
  • Run with docker-compose up

Option 2: Running Console+Router and build your own Console image

cp templates/docker-compose-server.yaml docker-compose.yaml
cp templates/nginx-default.conf nginx.conf
  • Get a certificate (https://certbot.eff.org/instructions)
  • Update nginx.conf with cert and key information
  • In .env, set SOCKET_CHECK_ORIGIN to your host domain
  • Build with docker-compose build
  • Run with docker-compose up

Option 3: Running Console+Router with Docker locally

cp templates/docker-compose-local.yaml docker-compose.yaml
  • Build with docker-compose build
  • Run with docker-compose up

Now you can visit localhost:4000 from your browser.

Opt in to use an IP Filter for Stripe Transactions

In the event that Stripe requires you to restrict credit card payments to certain countries or cities, you may opt in to use the IP filter implemented in the ConsoleWeb.IPFilter module.

To do so, please obtain a MaxMind key and download the database onto the host machine: (https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&suffix=tar.gz&license_key=${MAXMIND_KEY})

Please note you'll have to regularly update this database.

In your docker-compose file under console, add the following:

volumes:
  - "/host/path/to/GeoLite2-City.mmdb:/app/GeoLite2-City.mmdb"

Then, you may set the following variables in your .env file.

UNSUPPORTED_COUNTRIES=CU,IR,KP,SY,RU # or a comma-separated list of the ISO Alpha-2 codes of countries to be restricted
UNSUPPORTED_CITIES=Luhansk,Donetsk # or a comma-separated list of the names of cities to be restricted
UNSUPPORTED_UKR_SUBDIVISIONS=43,40 # or a comma-separated list of the ISO codes for Ukranian subdivisions to be restricted

Upgrading your open source Console+Router (Applies to Option 1 only)

  • Bring down your server with docker-compose down
  • Pull down and run the latest released Quay images with docker-compose up
  • If there are db migrations in the upgrade commits, docker-compose up will run these migrations (Keep an eye on the logs for migration errors to file a GH issue, you should not have to manually migrate the db)
  • If needed, you can manually migrate the db with docker exec -it helium_console /bin/bash, then _build/prod/rel/console/bin/console eval "Console.Release.migrate"

Upgrading your open source Console+Router (Applies to Option 2 and 3 only)

  • Pull down the latest master branch with git
  • Build with docker-compose build, you do not have to bring down your server until this completes
  • Bring down your server with docker-compose down, then run your new build with docker-compose up
  • If there are db migrations in the upgrade commits, docker-compose up will run these migrations (Keep an eye on the logs for migration errors to file a GH issue, you should not have to manually migrate the db)
  • If needed, you can manually migrate the db with docker exec -it helium_console /bin/bash, then _build/prod/rel/console/bin/console eval "Console.Release.migrate"

Keep your Console invite only

  • Set USER_INVTE_ONLY to true in your .env file
  • Add approved users to your db INSERT INTO users (id, email, password_hash, inserted_at, updated_at) values (1, '[email protected]', 'hash', NOW(), NOW());

Customizing your Console branding

Running Console Development Environment without Router

To start your Phoenix server:

  • Install dependencies with mix deps.get
  • Create and migrate your database with mix ecto.setup
  • Install Node.js dependencies with cd assets && yarn
  • Start Phoenix with mix phx.server

Now you can visit localhost:4000 from your browser.

Questions

If you run into any issues or you have any questions about how to get started contributing, feel free to reach out on the #console channel in the official Helium Community Discord server!

console's People

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

console's Issues

Audit Trails

We'll need to make sure to keep and display audit trails for all transactions.

These will include:

  • Inviting members to teams
  • Changing membership roles
  • All transactions made with a team's private key
  • Creating/removing devices/gateways/channels
  • ...

Private Keys

Teams also will own the blockchain private key and users with admin/owner permissions can make transactions on behalf of the team.

During team creation, we'll need to use the blockchain node application to generate a private key and store it, encrypted, as part of the team record

Packet graph

show events that have packet info in a realtime graph

Env file should contains all the Database configuration and mention Docker-Compose relation

In the current .env file we have only

DATABASE_DB=console
DATABASE_HOST=postgres

I think we should have:

# make sure your setting matches the DockerCompose
DATABASE_DB=console
DATABASE_HOST=postgres
DATABASE_USER=console
DATABASE_PASSWORD=xxx

I also propose to add in docker-compose.yml file

postgres:
    image: postgres
    container_name: helium_postgres
    restart: always
    environment:
        - POSTGRES_DB=console
        - POSTGRES_PASSWORD=postgres
        - POSTGRES_USER=console
    volumes:
      - "./data/postgres/:/var/lib/postgresql/data"

Team Invitations

allow users with role of owner/admin to invite other users to a team via email

Error messages

show error messages in react when phoenix responds with an error status and json like:

{
  "errors":  [...]
}

Release.exs could be .template

As this file needs to be modified, the use of a .template exenstion could help in updating the source tree w/o conflicts.

channel setup flow

We should port our existing channel setup flow from symphony into console

CRUD API for Gateways, Devices, Channels

These will just have some basic attributes on them for now so that we can get things wired up

Gateways

  • name
  • mac
  • latitude
  • longitude

Devices

  • name
  • mac
  • public_key

Channels

  • name
  • type
  • credentials (encrypted map?)
  • active

Confirm user password on registration

  • add another field to the registration form for "confirm password"
  • verify server-side that the passwords match in order for the registration to be successful
  • (optional?) confirm the passwords match client-side for a better UX

Forgot password feature

I think we can use Guardian to build the token. We can use the typ claim with a value of "reset_password" instead of "access" and a ttl of 1 hour or whatever is suitable.

Gateway mapping

gateways have a latitude and longitude properties. We'll need to visualize collections of gateways and individuals on a map. we should make a reusable mapbox component for this

unclear console message

I got the following error message:

21:47:26.297 [error] Could not check origin for Phoenix.Socket transport.
helium_console | 
helium_console | Origin of the request: https://console.xxxxxx.com
helium_console | 
helium_console | This happens when you are attempting a socket connection to
helium_console | a different host than the one configured in your config/
helium_console | files. For example, in development the host is configured
helium_console | to "localhost" but you may be trying to access it from
helium_console | "127.0.0.1". To fix this issue, you may either:
helium_console | 
helium_console |   1. update [url: [host: ...]] to your actual host in the
helium_console |      config file for your current environment (recommended)
helium_console | 
helium_console |   2. pass the :check_origin option when configuring your
helium_console |      endpoint or when configuring the transport in your
helium_console |      UserSocket module, explicitly outlining which origins
helium_console |      are allowed:
helium_console | 
helium_console |         check_origin: ["https://example.com",
helium_console |                        "//another.com:888", "//other.com"]

But the release.exs file contains the right domaine name corresponding to that one : https://console.xxxxxx.com
I see no check_origin mension in the configuration file. What is the best to do ?

Handle successful login

Let's redirect to "/secret" for now after a successful login so that it's clear that the login was successful. We should also hide the login/register etc links and prevent users from visiting "/login", redirecting back to "/secret". We'll want to make sure that the "redirect after login" path is stored in a single place so that once we have a real place to redirect them to, we can just change it in one place.

ROUTER_SECRETS requires timestamp?

ROUTER_SECRETS=[Unix Timestamp:Random 64 char secret key]

What is the purpose of the Unix timestamp? Can it be any timestamp? Should it be "now"?

Streamline OSS Build

There are some file edits required by the user. I wonder if we can automate/streamline this.

Perhaps we copy the source into the build container and use sed to make these changes?
Perhaps we can reference a /config/docker.exs instead of editing /config/prod.exs?

Follow instructions at the top of /config/prod.exs
Follow instructions at the bottom of /assets/webpack.config.js
Update host at the top of /config/releases.exs

Handle JWT expiration

When a JWT passes its TTL, we should handle that gracefully and redirect to login.

Also, if the client detects that a JWT is close to expiring, it could refresh it using Guardian's refresh token feature.

Check origin change

Since the new console update, I've got this error message

helium_console | 08:24:31.504 [error] Could not check origin for Phoenix.Socket transport.
helium_console | 
helium_console | Origin of the request: https://console.helium-iot.eu
helium_console | 
helium_console | This happens when you are attempting a socket connection to
helium_console | a different host than the one configured in your config/
helium_console | files. For example, in development the host is configured
helium_console | to "localhost" but you may be trying to access it from
helium_console | "127.0.0.1". To fix this issue, you may either:
helium_console | 
helium_console |   1. update [url: [host: ...]] to your actual host in the
helium_console |      config file for your current environment (recommended)
helium_console | 
helium_console |   2. pass the :check_origin option when configuring your
helium_console |      endpoint or when configuring the transport in your
helium_console |      UserSocket module, explicitly outlining which origins
helium_console |      are allowed:
helium_console | 
helium_console |         check_origin: ["https://example.com",
helium_console |                        "//another.com:888", "//other.com"]
helium_console | 

apparently the devices stopped to connect

I've applied the 2nd option proposed adding check origin ... and get console crash as a loop

helium_console | ERROR! Config provider Config.Reader failed with:
helium_console | ** (SyntaxError) _build/prod/rel/console/releases/0.0.1/releases.exs:15: syntax error before: cache_static_manifest
helium_console |     (elixir) src/elixir.erl:245: :elixir.eval/3
helium_console |     (elixir) lib/code.ex:240: Code.eval_string/3
helium_console |     (elixir) lib/config.ex:219: Config.__eval__!/2
helium_console |     (elixir) lib/config/reader.ex:44: Config.Reader.read!/2
helium_console |     (elixir) lib/config/reader.ex:24: Config.Reader.load/2
helium_console |     (elixir) lib/config/provider.ex:206: anonymous fn/2 in Config.Provider.run_providers/2
helium_console |     (elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3
helium_console | 
helium_console | {"init terminating in do_boot",{#{'__exception__'=>true,'__struct__'=>'Elixir.SyntaxError',description=><<"syntax error before: cache_static_manifest">>,file=><<"/app/_build/prod/rel/console/releases/0.0.1/releases.exs">>,line=>15},[{elixir,eval,3,[{file,"src/elixir.erl"},{line,245}]},{'Elixir.Code',eval_string,3,[{file,"lib/code.ex"},{line,240}]},{'Elixir.Config','__eval__!',2,[{file,"lib/config.ex"},{line,219}]},{'Elixir.Config.Reader','read!',2,[{file,"lib/config/reader.ex"},{line,44}]},{'Elixir.Config.Reader',load,2,[{file,"lib/config/reader.ex"},{line,24}]},{'Elixir.Config.Provider','-run_providers/2-fun-0-',2,[{file,"lib/config/provider.ex"},{line,206}]},{'Elixir.Enum','-reduce/3-lists^foldl/2-0-',3,[{file,"lib/enum.ex"},{line,1948}]}]}}
helium_console | init terminating in do_boot ({,[{elixir,eval,3,[{_},{_}]},{Elixir.Code,eval_string,3,[{_},{_}]},{Elixir.Config,__eval__!,2,[{_},{_}]},{Elixir.Config.Reader,read!,2,[{_},{_}]},{Elixir.Config.Reader,loa

xor transaction billing

Could be have a way to bill the xor transaction to the final consumer by decreasing it's DC amount ?

Failed Network Calls cause Firefox issues

When testing with @mfalkvidd, we could not use Firefox. Some failed calls to services such as Amplitude were upsetting the browser. Switching to Chrome was fine. We probably want to do a better job of disabling these optional services when they are not configured to fix this issue.

Events

Events can pertain to some combination of Gateway, Device and/or Channel.

they have:

  • description:string
  • direction (inbound vs outbound)
  • payload:text
  • payload_size:integer
  • reported_at:datetime
  • rssi:float
  • signal_strength
  • status:string

How to change the console base url ?

I would like the console to repond on localhost:4000/console/ to have it as part of a more global service.
Is there a configuration I can use somewhere ?
not sure about ENV_DOMAIN if it can be use for this ?

Test interface and simulation for users without hardware

As a user I want to be able to test the Helium router and cloud channel integrations without having to buy hardware initially.

To solve this I suggest exposing an interface to the dashboard and channels as "virtual atoms" and "virtual gateways" which can interface with a standard channel and any cloud service through it. The virtual atoms can be transmitting data via some MQTT pub/sub or REST style API (or something else?) to simulate an atom sending data end-to-end.

Additional features of the virtual devices could be tools to introduce/adjust network jitter, interference, latency at different branches, etc..

Need success flash after resend verification

right now it works, but there's no user feedback.

We also probably want to regenerate the confirmation token on this action. For security but also because there's a failure case where if confirmation_token is null, this action fails.

Create additional teams & switch between them

Previously we used the session to track current team. Since we're using API routes without access to the session, we'll need a new strategy.

For reference, the data model is:

users <--> memberships <--> teams

Two ideas I can think of:

JWT

When the user logs in, we issue a JWT that they use to authenticate themselves for each subsequent request. We could store the current team as a field on the JWT so that all requests made with that token are scoped against that team. When the user switches teams, it is issued a different token that it stores in place of its existing token.

Field on memberships

We could also track a user's current team as a boolean field or a timestamp on memberships. When a user switches teams, the new team's membership record has its timestamp updated and all future requests will apply to the team with the most-recently-switched-to membership

Even if we go with JWT, I think we might need some kind of timestamp on memberships so that when a user logs in, we take them back to the team they were viewing last.

I kind of like the cleanliness of scoping an access token to the combination of a user and team

Integration HTTP fail on deployed instance of console

Not clear why but the same HTTP integration working in console.helium.com is not working on my instance.
I just getting the following:

foxtrackr | error | Mar 20, 2021 9:08:54.428 PM | Integration Response

I propose to add the HTTP response code from the server.

My question here is : how to debug this kind of issues as there is no reason it comes from the backend side.

New session error

I didn’t figure out how to configure captcha, so I temporarily cut it out.
After registration and confirmation of the letter (but the letter does not arrive at the mail), an error occurs when creating a new session.

def create(conn, %{"session" => session_params) do
with {:ok, %User{} = user} <- Auth.authenticate(session_params),
current_team <- Teams.current_team_for(user),
jwt <- Auth.generate_session_token(user, current_team) do
AuditTrails.create_audit_trail("user_account", "login", user)

  if user.twofactor do
    conn
    |> put_status(:created)
    |> render("show.json", user: user)
  else
    conn
    |> put_status(:created)
    |> render("show.json", user: user, jwt: jwt, skip2fa: !Auth.should_skip_2fa_prompt?(user.last_2fa_skipped_at))
    # TODO: why jwt if twofactor?
  end
end

end

== Compilation error in file lib/console_web/controllers/session_controller.ex ==
** (SyntaxError) lib/console_web/controllers/session_controller.ex:11: unexpected token: ). The "{" at line 11 is missing terminator "}"

teams and private keys

The console will behave much like coinbase in that it will store a user's private keys for them (store in a db? something else? bones to decide) that allows them to transact within the web app. Users will not be able to access their private keys.

Who owns the private keys?

  • the org or team will own the private key
  • users with admin/top level permissions will be able to manage the wallet (add credit card, set up transaction bids, fund wallet, move funds)

Default Teams

  • in Dashboard, personal teams were automatically created on sign up. the personal team name would be the firstname/lastname of a new user. we won't be doing this for console
  • instead, as part of the sign up flow, users are required to name their team. Our expectation is that they will name the team after their company name (we expect console to be used by corporations). this user will also get admin privileges by default. This gives the team a relevant team name to their use case.

Creating a new team

  • all users are can create a new team. they'll have to go through the same onboarding process (name the team, invite users)

Switching between teams

  • as with dashboard, users in console are able to switch between teams using the same login credentials

Teams

users <--> teams is a has_and_belongs_to_many relationship. The join table is called Memberships and includes the role a user has on that team (owner, admin, member).

Users must belong to a team and by default will provide a name for their team during signup unless signing up with an invitation to join another team, in which case they will just join that team. (Note there will be no distinction between personal/organization teams)

gateways, devices, and channels all belong to teams and can be transferred between teams if the user's role is admin or owner.

For reference, our Rails classes are:

=> class Team < ApplicationRecord {
     :created_at => :datetime,
             :id => :integer,
  :mqtt_password => :string,
           :name => :string,
       :personal => :boolean,
           :slug => :string,
          :token => :string,
     :updated_at => :datetime
}
=> class Membership < ApplicationRecord {
              :created_at => :datetime,
                      :id => :integer,
  :invitation_accepted_at => :datetime,
   :invitation_created_at => :datetime,
        :invitation_email => :string,
        :invitation_token => :string,
              :inviter_id => :integer,
                    :role => :string,
                 :team_id => :integer,
                   :token => :string,
              :updated_at => :datetime,
                 :user_id => :integer
}

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.