summaryrefslogtreecommitdiffstats
path: root/status_app.rb
blob: a273c4bfe947723e593a6cf3ddcf85f22f955b0d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# frozen_string_literal: true

require 'json'
require 'sinatra/base'
require 'slim/include'
require 'slim/smart'

require './lib/mattermost_helper'
require './lib/mail_helper'
require './lib/sqlite_helper'
require './lib/emojis'
require './lib/main'

# Main Sinatra application, contains only routing statements
class StatusApp < Sinatra::Base
  configure :production, :development do
    enable :logging
    disable :method_override, :sessions
  end

  include MailHelper
  include MattermostHelper
  include SqliteHelper
  include Main

  def key_value_unless_blank(details, key)
    value = details[key]&.strip
    return value if value && value != ''
    nil
  end

  def convert_emojis(text)
    copy = text.dup
    EMOJIS_LIST.each do |k, v|
      copy.gsub!(k, v)
    end
    copy
  end

  before do
    load_config
    init_db
    init_default_value
  end

  get '/' do
    redirect to("/status?#{@auth_chain}") if check_token
    @title = 'Status index'
    slim :index
  end

  get '/status' do
    redirect to('/') unless check_token
    @title = 'My status'
    @my_status = @current_status['status']
    if @my_status == 'present'
      @next_status = 'absent'
    else
      @next_status = 'present'
    end
    slim :status
  end

  post '/status' do
    redirect to('/') unless check_token
    details = params.select { |k, _| ['status', 'eta'].include?(k) }
    details['eta'] = '' if details['status'] == 'present'
    update_status(details, @current_status['email'])
    send_mattermost_notification
    redirect to("/status?#{@auth_chain}")
  end

  post '/details' do
    redirect to('/') unless check_token
    possible_keys = @config['custom_fields']&.map { |d| d['name'] } || []
    possible_keys += ['name', 'handle']
    details = params.select { |k, _| possible_keys.include?(k) }
    update_status(details, @current_status['email'])
    redirect to("/status?saved=&#{@auth_chain}")
  end

  get '/list' do
    redirect to('/') unless check_token
    @title = 'Presences'
    @presence = fetch_all_statuses(params['filter'])
    slim :list
  end

  post '/login' do
    email = params[:email].strip
    redirect to('/') if email == ''
    mail_data = params[:email].split('@')
    redirect to('/') if mail_data[1] != @config['domain']
    generate_and_send_new_token(email)
    redirect to('/?please_wait=')
  end

  get '/revoke' do
    generate_and_send_new_token(@current_status['email']) if check_token
    redirect to('/?please_wait=')
  end

  get '/delete' do
    remove_status(@current_status['email']) if check_token
    redirect to('/')
  end

  post '/mattermost' do
    content_type 'application/json'
    check_token = @config.dig('mattermost', 'token')
    if !check_token || params[:token] != check_token
      return JSON.dump({ 'response_type' => 'ephemeral',
                         'text' => 'Not authorized' })
    end
    output = { 'response_type' => 'ephemeral', 'text' => params[:text] }
    output.merge!(
      update_details_from_mattermost(params[:text], params[:user_name])
    )
    public_channel = @config.dig('mattermost', 'public_channel')
    if public_channel && output['response_type'] == 'in_channel' \
       && params[:channel_id] != public_channel
      output['channel_id'] = public_channel
    end
    JSON.dump(output)
  end
end