diff --git a/Gemfile b/Gemfile deleted file mode 100644 index e5212d2..0000000 --- a/Gemfile +++ /dev/null @@ -1,11 +0,0 @@ -source "https://rubygems.org" - -gem "base64" -gem "erb" -gem "json" -gem "net-http" -gem "sequel" -gem "sinatra" -gem "uri" -gem "xxhash" -gem "zlib" diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 626f954..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,52 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - base64 (0.3.0) - bigdecimal (3.2.2) - erb (5.0.1) - json (2.12.2) - logger (1.7.0) - mustermann (3.0.3) - ruby2_keywords (~> 0.0.1) - net-http (0.6.0) - uri - rack (3.1.16) - rack-protection (4.1.1) - base64 (>= 0.1.0) - logger (>= 1.6.0) - rack (>= 3.0.0, < 4) - rack-session (2.1.1) - base64 (>= 0.1.0) - rack (>= 3.0.0) - ruby2_keywords (0.0.5) - sequel (5.93.0) - bigdecimal - sinatra (4.1.1) - logger (>= 1.6.0) - mustermann (~> 3.0) - rack (>= 3.0.0, < 4) - rack-protection (= 4.1.1) - rack-session (>= 2.0.0, < 3) - tilt (~> 2.0) - tilt (2.6.0) - uri (1.0.3) - xxhash (0.6.0) - zlib (3.2.1) - -PLATFORMS - ruby - x86_64-linux - -DEPENDENCIES - base64 - erb - json - net-http - sequel - sinatra - uri - xxhash - zlib - -BUNDLED WITH - 2.6.9 diff --git a/dev.fish b/dev.fish deleted file mode 100644 index 07615e5..0000000 --- a/dev.fish +++ /dev/null @@ -1,30 +0,0 @@ -set pipe_path /tmp/infin -set oldsum (cat (find . \( -name '*.rb' -o -name '*.js' \) | sort) | md5sum) -if not test -e infinsweeper.db - sqlite3 infinsweeper.db < schema.sql -end -pkill ruby -ruby main.rb -p8080 & -echo "" > $pipe_path -while true - sleep 1 - set newsum (cat (find . \( -name '*.rb' -o -name '*.js' \) | sort) | md5sum) - echo $newsum $oldsum - if test "$oldsum" != "$newsum" - set oldsum $newsum - pkill ruby - ruby main.rb -p8080 & - end - if set line (cat $pipe_path) - echo $line - if test "$line" = "die" - pkill ruby - echo "" > $pipe_path - exit - end - if test "$line" = "open" - echo "" > $pipe_path - xdg-open http://localhost:8080 - end - end -end diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5f236ab --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1790185690, + "narHash": "sha256-xJ+X4hBtOcAFGBOe5nAMyMUeF9foJBmIOu3NjBqBycU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4975466d324710c576dc11ad614684e6bd8cad8e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..d177f92 --- /dev/null +++ b/flake.nix @@ -0,0 +1,49 @@ +{ + description = "Infinsweeper"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = + { nixpkgs, ... }: + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + + ruby = pkgs.ruby.withPackages ( + p: with p; [ + sqlite3 + sequel + rackup + puma + sinatra + ] + ); + + app = pkgs.stdenv.mkDerivation { + pname = "infinsweeper"; + version = "0.1.0"; + src = ./.; + buildInputs = [ ruby ]; + installPhase = '' + mkdir -p $out + cp -r . $out/ + ''; + postFixup = '' + substituteInPlace $out/bin/infinsweeper \ + --replace-fail '#!/usr/bin/env ruby' '#!${ruby}/bin/ruby' + ''; + }; + in + { + packages.${system}.default = app; + + devShells.${system}.default = pkgs.mkShell { + packages = [ + ruby + pkgs.sqlite + ]; + }; + }; +} diff --git a/main.rb b/main.rb index 6db71b4..4f2d420 100644 --- a/main.rb +++ b/main.rb @@ -5,7 +5,6 @@ require "net/http" require "sequel" require "sinatra" require "uri" -require "xxhash" require "zlib" ALPHANUM = [*"0".."9", *"A".."Z", *"a".."z", "-", "_"].freeze @@ -21,15 +20,32 @@ end load "logman.rb" # Logman.log ENV_HASH.inspect -db_file = File.expand_path("infinsweeper.db") +db_file = File.expand_path("infinsweeper.db", __dir__) DB = Sequel.connect("sqlite:///#{db_file}", single_threaded: false) DB.run("PRAGMA foreign_keys = ON;") +DB.create_table? :Players do + String :username, primary_key: true + String :email, unique: true + File :digest + File :data + String :activation_code + String :new_pass_code + DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP +end +DB.create_table? :SignedInUsers do + String :code, primary_key: true + String :player + DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP + DateTime :last_used_at, default: Sequel::CURRENT_TIMESTAMP + foreign_key [:player], :Players, key: :username, on_delete: :cascade +end $active_users = DB[:SignedInUsers].all.map { |x| [x[:code], x[:player]] }.to_h load "mailer.rb" load "players.rb" load "session.rb" +set :port, ENV.fetch("PORT", 5161) set :public_folder, "public" get "/" do diff --git a/players.rb b/players.rb index 94222e0..3c3e7a3 100644 --- a/players.rb +++ b/players.rb @@ -18,7 +18,7 @@ module Players raise ArgumentError, "Password must be at least 8 characters and of valid format." unless pass.match?(/\A[a-zA-Z0-9_.!?@#$%^&*()+=-]+\z/) && pass.length >= 8 - digest = XXhash.xxh32(pass, ENV_HASH["SALT"]) + digest = Zlib.crc32(pass, ENV_HASH["SALT"]) code = ENV_HASH["ENV"] == "prod" ? Array.new(24) { ALPHANUM.sample }.join : "!" DB[ @@ -78,7 +78,7 @@ module Players end def self.authorized?(username, pass) - digest = XXhash.xxh32(pass, ENV_HASH["SALT"]) + digest = Zlib.crc32(pass, ENV_HASH["SALT"]) Logman.log "Authorized: #{username} & #{digest}" player = self[username] player && player[:digest].to_i == digest.to_i ? player : false