markdownr 0.5.8 → 0.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44c223ecfa0f81c35d2d3d89a5c316eb2adc7f0a343db241185dc828268d3527
4
- data.tar.gz: 7b87a1fed84d540c89bc92bea8de754eee3d680ba93f952ad4b23c7150aa06b3
3
+ metadata.gz: afce137b9a88a74b444125a02f30a12dba75210bd3e223052542bea4ea39d4bf
4
+ data.tar.gz: b2cebe87af19b5f2ec26270b6f5b79d05472357e3dcb6916b9047ca69a27a3d5
5
5
  SHA512:
6
- metadata.gz: 8eb259d062a13af47d3126ea380777e01aba1f1e6bc9401fb2f05c8277e9a827d6e16f9299e96768236574114875c0f4d2b5ab273094513c71670afa765f3e12
7
- data.tar.gz: 56fda7d165fecbec5b46d8a496d257aa38164684779225bfac6e1d9da00df3fb8da3e90fbd4c58c435f2680a21869271f06c4b3791df48b9ac1b6d64e7359277
6
+ metadata.gz: 94c9857b53bad2ac793ae931607ee74e06f02f2410a029a0cfd5568754daa4befd6d913257ec9fbb673c594b1701ce4a9ef7e2f7681dba7c16f0406e6a8886ea
7
+ data.tar.gz: b55430f749eadd254de9b2feffd9d9aef09566166d47f33d42be29c58d826955d42a47f7c2fb704ccc807e0748e3b1bfcb7a245c558a38d014acabef2d3894c9
@@ -0,0 +1,5 @@
1
+ FROM ruby:3.4-slim
2
+ RUN apt-get update && apt-get install -y build-essential && gem install markdownr
3
+ WORKDIR /data
4
+ CMD ["markdownr", "--behind-proxy", "-b", "0.0.0.0", "/data"]
5
+
data/bin/markdownr CHANGED
@@ -23,6 +23,14 @@ OptionParser.new do |opts|
23
23
  options[:allow_robots] = true
24
24
  end
25
25
 
26
+ opts.on("--behind-proxy", "Trust X-Forwarded-For for client IP (use when behind a reverse proxy like Caddy)") do
27
+ options[:behind_proxy] = true
28
+ end
29
+
30
+ opts.on("-i", "--index-file FILENAME", "Render this file instead of the directory listing when present (e.g. index.md, moc.md)") do |f|
31
+ options[:index_file] = f
32
+ end
33
+
26
34
  opts.on("--no-link-tooltips", "Disable preview tooltips for local markdown links") do
27
35
  options[:link_tooltips] = false
28
36
  end
@@ -46,8 +54,10 @@ unless File.directory?(dir)
46
54
  end
47
55
 
48
56
  MarkdownServer::App.set :root_dir, dir
57
+ MarkdownServer::App.set :behind_proxy, options[:behind_proxy] || false
49
58
  MarkdownServer::App.set :custom_title, options[:title]
50
59
  MarkdownServer::App.set :allow_robots, options[:allow_robots] || false
60
+ MarkdownServer::App.set :index_file, options[:index_file]
51
61
  MarkdownServer::App.set :link_tooltips, options.fetch(:link_tooltips, true)
52
62
  MarkdownServer::App.set :hard_wrap, options.fetch(:hard_wrap, true)
53
63
  MarkdownServer::App.set :port, options[:port]
@@ -0,0 +1,12 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ IMAGE="$DOCKER_HUB_USERNAME/markdownr:latest"
5
+
6
+ echo "$DOCKER_HUB_TOKEN" | docker login -u "$DOCKER_HUB_USERNAME" --password-stdin
7
+
8
+ docker build --no-cache -f bin/Dockerfile.markdownr -t "$IMAGE" .
9
+
10
+ docker push "$IMAGE"
11
+
12
+ docker logout
@@ -9,6 +9,7 @@ require "cgi"
9
9
  require "pathname"
10
10
  require "set"
11
11
  require "net/http"
12
+ require "base64"
12
13
 
13
14
  module MarkdownServer
14
15
  class App < Sinatra::Base
@@ -20,11 +21,15 @@ module MarkdownServer
20
21
  set :root_dir, Dir.pwd
21
22
  set :custom_title, nil
22
23
  set :allow_robots, false
24
+ set :index_file, nil
23
25
  set :link_tooltips, true
24
26
  set :hard_wrap, true
25
27
  set :show_exceptions, false
26
28
  set :protection, false
27
29
  set :host_authorization, { permitted_hosts: [] }
30
+ set :behind_proxy, false
31
+ set :session_secret, ENV.fetch("MARKDOWNR_SESSION_SECRET", SecureRandom.hex(64))
32
+ set :sessions, key: "markdownr_session", same_site: :strict, httponly: true
28
33
  end
29
34
 
30
35
  helpers do
@@ -636,8 +641,10 @@ module MarkdownServer
636
641
  inflections.sort_by! { |i| -i[:freq] }
637
642
  if inflections.any?
638
643
  rows = inflections.map { |i|
639
- link = i[:href] ? %(<a href="#{h(i[:href])}" target="_blank" rel="noopener">#{h(i[:word])}</a>) : h(i[:word])
640
- %(<tr><td>#{link}</td><td class="blb-right">#{i[:freq]}x</td></tr>)
644
+ match = i[:word] == word
645
+ cls = match ? ' class="blb-match"' : ""
646
+ link = i[:href] ? %(<a href="#{h(i[:href])}" target="_blank" rel="noopener">#{h(i[:word])}</a>) : h(i[:word])
647
+ %(<tr><td#{cls}>#{link}</td><td class="blb-right">#{i[:freq]}x</td></tr>)
641
648
  }.join
642
649
  infl_html = %(<h4 class="blb-heading">Inflections</h4>) +
643
650
  %(<table class="blb-table"><thead><tr><th class="blb-th">Form</th>) +
@@ -727,6 +734,43 @@ module MarkdownServer
727
734
  raise RegexpError, e.message
728
735
  end
729
736
 
737
+ def client_ip
738
+ if settings.behind_proxy
739
+ fwd = env["HTTP_X_FORWARDED_FOR"].to_s.split(",").map(&:strip).first
740
+ fwd && !fwd.empty? ? fwd : env["REMOTE_ADDR"]
741
+ else
742
+ env["REMOTE_ADDR"]
743
+ end
744
+ end
745
+
746
+ def setup_config
747
+ @setup_config ||= begin
748
+ path = File.join(root_dir, ".setup.yml")
749
+ (File.exist?(path) && YAML.safe_load(File.read(path))) || {}
750
+ rescue StandardError
751
+ {}
752
+ end
753
+ end
754
+
755
+ def admin?
756
+ return true if session[:admin]
757
+
758
+ adm = setup_config["admin"]
759
+ return false unless adm.is_a?(Hash)
760
+
761
+ return true if adm["ip"].to_s.strip == client_ip
762
+
763
+ if adm["user"] && adm["pw"]
764
+ auth = request.env["HTTP_AUTHORIZATION"].to_s
765
+ if auth.start_with?("Basic ")
766
+ user, pw = Base64.decode64(auth[6..]).split(":", 2)
767
+ return true if user == adm["user"].to_s && pw == adm["pw"].to_s
768
+ end
769
+ end
770
+
771
+ false
772
+ end
773
+
730
774
  end
731
775
 
732
776
  # Routes
@@ -744,6 +788,41 @@ module MarkdownServer
744
788
  redirect "/browse/"
745
789
  end
746
790
 
791
+ get "/setup-info" do
792
+ @title = "Setup Info"
793
+ @client_ip = client_ip
794
+ @is_admin = admin?
795
+ @served_path = root_dir if @is_admin
796
+ @public_config = setup_config.reject { |k, _| k == "admin" }
797
+ erb :setup_info
798
+ end
799
+
800
+ get "/admin/login" do
801
+ @title = "Admin Login"
802
+ @error = session.delete(:login_error)
803
+ @return_to = params[:return_to]
804
+ erb :admin_login
805
+ end
806
+
807
+ post "/admin/login" do
808
+ adm = setup_config["admin"]
809
+ if adm.is_a?(Hash) &&
810
+ params[:username] == adm["user"].to_s &&
811
+ params[:password] == adm["pw"].to_s
812
+ session[:admin] = true
813
+ return_to = params[:return_to].to_s
814
+ redirect(return_to.start_with?("/") ? return_to : "/")
815
+ else
816
+ session[:login_error] = "Invalid username or password."
817
+ redirect "/admin/login"
818
+ end
819
+ end
820
+
821
+ get "/admin/logout" do
822
+ session.clear
823
+ redirect "/"
824
+ end
825
+
747
826
  get "/browse/?*" do
748
827
  requested = params["splat"].first.to_s
749
828
  requested = requested.chomp("/")
@@ -755,7 +834,14 @@ module MarkdownServer
755
834
  end
756
835
 
757
836
  if File.directory?(real_path)
758
- render_directory(real_path, requested)
837
+ index = settings.index_file
838
+ index_path = index && File.join(real_path, index)
839
+ if index_path && File.file?(index_path)
840
+ index_rel = requested.empty? ? index : "#{requested}/#{index}"
841
+ render_file(index_path, index_rel)
842
+ else
843
+ render_directory(real_path, requested)
844
+ end
759
845
  else
760
846
  render_file(real_path, requested)
761
847
  end
@@ -1,3 +1,3 @@
1
1
  module MarkdownServer
2
- VERSION = "0.5.8"
2
+ VERSION = "0.5.10"
3
3
  end
@@ -0,0 +1,24 @@
1
+ <div class="title-bar">
2
+ <h1 class="page-title">Admin Login</h1>
3
+ </div>
4
+
5
+ <div class="md-content" style="max-width: 360px;">
6
+ <% if @error %>
7
+ <p style="color: #b33; margin-bottom: 1rem;"><%= h(@error) %></p>
8
+ <% end %>
9
+
10
+ <form method="post" action="/admin/login">
11
+ <input type="hidden" name="return_to" value="<%= h(@return_to.to_s) %>">
12
+ <table class="meta-table" style="margin-bottom: 1rem;">
13
+ <tr>
14
+ <th class="blb-th">Username</th>
15
+ <td><input type="text" name="username" autofocus style="width:100%;padding:2px 4px;"></td>
16
+ </tr>
17
+ <tr>
18
+ <th class="blb-th">Password</th>
19
+ <td><input type="password" name="password" style="width:100%;padding:2px 4px;"></td>
20
+ </tr>
21
+ </table>
22
+ <button type="submit" style="padding:4px 16px;">Log in</button>
23
+ </form>
24
+ </div>
data/views/layout.erb CHANGED
@@ -319,10 +319,12 @@
319
319
  a.wiki-link {
320
320
  color: #6a8e3e;
321
321
  border-bottom: 1px dashed #6a8e3e;
322
+ margin: 0 0.2rem;
322
323
  }
323
324
  span.wiki-link.broken {
324
325
  color: #c44;
325
326
  border-bottom: 1px dashed #c44;
327
+ margin: 0 0.2rem;
326
328
  }
327
329
 
328
330
  /* Raw/code view */
@@ -0,0 +1,28 @@
1
+ <div class="title-bar">
2
+ <h1 class="page-title">Setup Info</h1>
3
+ </div>
4
+
5
+ <div class="md-content">
6
+ <% if @is_admin %>
7
+ <p><strong>You are an administrator.</strong></p>
8
+ <% end %>
9
+
10
+ <table class="meta-table">
11
+ <tr><th>Your IP</th><td><%= h(@client_ip) %></td></tr>
12
+ <% if @served_path %>
13
+ <tr><th>Serving</th><td><%= h(@served_path) %></td></tr>
14
+ <% end %>
15
+ </table>
16
+
17
+ <% unless @public_config.empty? %>
18
+ <h3>Configuration</h3>
19
+ <table class="meta-table">
20
+ <% @public_config.each do |key, value| %>
21
+ <tr>
22
+ <th><%= h(key.to_s) %></th>
23
+ <td><%= h(value.to_s) %></td>
24
+ </tr>
25
+ <% end %>
26
+ </table>
27
+ <% end %>
28
+ </div>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdownr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.8
4
+ version: 0.5.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Dunn
@@ -100,15 +100,19 @@ executables:
100
100
  extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
+ - bin/Dockerfile.markdownr
103
104
  - bin/markdownr
105
+ - bin/push-to-docker
104
106
  - lib/markdown_server.rb
105
107
  - lib/markdown_server/app.rb
106
108
  - lib/markdown_server/version.rb
109
+ - views/admin_login.erb
107
110
  - views/directory.erb
108
111
  - views/layout.erb
109
112
  - views/markdown.erb
110
113
  - views/raw.erb
111
114
  - views/search.erb
115
+ - views/setup_info.erb
112
116
  homepage: https://github.com/brianmd/markdown-server
113
117
  licenses:
114
118
  - MIT