device_tracker 0.3.0

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.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +4 -0
  5. data/Gemfile +4 -0
  6. data/Rakefile +10 -0
  7. data/Readme.md +32 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +7 -0
  10. data/device_tracker.gemspec +63 -0
  11. data/exe/device_tracker +91 -0
  12. data/lib/device_tracker/app.rb +22 -0
  13. data/lib/device_tracker/config-schema.json +111 -0
  14. data/lib/device_tracker/config.ru +9 -0
  15. data/lib/device_tracker/controllers/application_controller.rb +226 -0
  16. data/lib/device_tracker/controllers/devices_controller.rb +315 -0
  17. data/lib/device_tracker/controllers/heartbeat_controller.rb +50 -0
  18. data/lib/device_tracker/controllers/os_controller.rb +38 -0
  19. data/lib/device_tracker/controllers/transactions_controller.rb +18 -0
  20. data/lib/device_tracker/controllers/users_controller.rb +131 -0
  21. data/lib/device_tracker/db/migrate/20150521071815_create_users.rb +14 -0
  22. data/lib/device_tracker/db/migrate/20150521082155_create_devices.rb +19 -0
  23. data/lib/device_tracker/db/migrate/20150521120335_create_operating_systems.rb +9 -0
  24. data/lib/device_tracker/db/migrate/20150527162242_create_transactions.rb +12 -0
  25. data/lib/device_tracker/db/migrate/20151027073050_create_heartbeat.rb +11 -0
  26. data/lib/device_tracker/db/migrate/20151028132946_add_user_verification.rb +8 -0
  27. data/lib/device_tracker/db/migrate/20151028141328_remove_is_active_from_users.rb +6 -0
  28. data/lib/device_tracker/db/migrate/20151029085629_add_password_reset_code_to_users.rb +8 -0
  29. data/lib/device_tracker/db/migrate/20151030130341_add_missing_column_to_devices.rb +8 -0
  30. data/lib/device_tracker/db/migrate/20151102141601_add_serial_number_to_devices.rb +8 -0
  31. data/lib/device_tracker/db/schema.rb +61 -0
  32. data/lib/device_tracker/db/seeds.rb +21 -0
  33. data/lib/device_tracker/dependencies.rb +16 -0
  34. data/lib/device_tracker/device_tracker.rb +18 -0
  35. data/lib/device_tracker/helpers/application_helper.rb +116 -0
  36. data/lib/device_tracker/helpers/user_helper.rb +24 -0
  37. data/lib/device_tracker/models/device.rb +42 -0
  38. data/lib/device_tracker/models/heartbeat.rb +7 -0
  39. data/lib/device_tracker/models/operating_system.rb +7 -0
  40. data/lib/device_tracker/models/transaction.rb +62 -0
  41. data/lib/device_tracker/models/user.rb +28 -0
  42. data/lib/device_tracker/public/css/bootstrap-sortable.css +100 -0
  43. data/lib/device_tracker/public/css/bootstrap.min.css +5 -0
  44. data/lib/device_tracker/public/css/custom.css +88 -0
  45. data/lib/device_tracker/public/favicon/android-chrome-144x144.png +0 -0
  46. data/lib/device_tracker/public/favicon/android-chrome-192x192.png +0 -0
  47. data/lib/device_tracker/public/favicon/android-chrome-36x36.png +0 -0
  48. data/lib/device_tracker/public/favicon/android-chrome-48x48.png +0 -0
  49. data/lib/device_tracker/public/favicon/android-chrome-72x72.png +0 -0
  50. data/lib/device_tracker/public/favicon/android-chrome-96x96.png +0 -0
  51. data/lib/device_tracker/public/favicon/apple-touch-icon-114x114.png +0 -0
  52. data/lib/device_tracker/public/favicon/apple-touch-icon-120x120.png +0 -0
  53. data/lib/device_tracker/public/favicon/apple-touch-icon-144x144.png +0 -0
  54. data/lib/device_tracker/public/favicon/apple-touch-icon-152x152.png +0 -0
  55. data/lib/device_tracker/public/favicon/apple-touch-icon-180x180.png +0 -0
  56. data/lib/device_tracker/public/favicon/apple-touch-icon-57x57.png +0 -0
  57. data/lib/device_tracker/public/favicon/apple-touch-icon-60x60.png +0 -0
  58. data/lib/device_tracker/public/favicon/apple-touch-icon-72x72.png +0 -0
  59. data/lib/device_tracker/public/favicon/apple-touch-icon-76x76.png +0 -0
  60. data/lib/device_tracker/public/favicon/apple-touch-icon-precomposed.png +0 -0
  61. data/lib/device_tracker/public/favicon/apple-touch-icon.png +0 -0
  62. data/lib/device_tracker/public/favicon/browserconfig.xml +12 -0
  63. data/lib/device_tracker/public/favicon/favicon-16x16.png +0 -0
  64. data/lib/device_tracker/public/favicon/favicon-32x32.png +0 -0
  65. data/lib/device_tracker/public/favicon/favicon-96x96.png +0 -0
  66. data/lib/device_tracker/public/favicon/favicon.ico +0 -0
  67. data/lib/device_tracker/public/favicon/manifest.json +41 -0
  68. data/lib/device_tracker/public/favicon/mstile-144x144.png +0 -0
  69. data/lib/device_tracker/public/favicon/mstile-150x150.png +0 -0
  70. data/lib/device_tracker/public/favicon/mstile-310x150.png +0 -0
  71. data/lib/device_tracker/public/favicon/mstile-310x310.png +0 -0
  72. data/lib/device_tracker/public/favicon/mstile-70x70.png +0 -0
  73. data/lib/device_tracker/public/favicon/safari-pinned-tab.svg +21 -0
  74. data/lib/device_tracker/public/favicon.png +0 -0
  75. data/lib/device_tracker/public/fonts/glyphicons-halflings-regular.eot +0 -0
  76. data/lib/device_tracker/public/fonts/glyphicons-halflings-regular.svg +288 -0
  77. data/lib/device_tracker/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  78. data/lib/device_tracker/public/fonts/glyphicons-halflings-regular.woff +0 -0
  79. data/lib/device_tracker/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  80. data/lib/device_tracker/public/js/bootstrap-sortable.js +211 -0
  81. data/lib/device_tracker/public/js/bootstrap.min.js +7 -0
  82. data/lib/device_tracker/public/js/jquery-2.1.4.min.js +4 -0
  83. data/lib/device_tracker/version.rb +4 -0
  84. data/lib/device_tracker/views/404.erb +25 -0
  85. data/lib/device_tracker/views/_alert.erb +5 -0
  86. data/lib/device_tracker/views/_device_form.erb +52 -0
  87. data/lib/device_tracker/views/_device_list.erb +47 -0
  88. data/lib/device_tracker/views/_footer.erb +3 -0
  89. data/lib/device_tracker/views/_header.erb +97 -0
  90. data/lib/device_tracker/views/_heartbeat_list.erb +25 -0
  91. data/lib/device_tracker/views/_user_form.erb +30 -0
  92. data/lib/device_tracker/views/devices/edit.erb +11 -0
  93. data/lib/device_tracker/views/devices/index.erb +12 -0
  94. data/lib/device_tracker/views/devices/new.erb +10 -0
  95. data/lib/device_tracker/views/devices/show.erb +283 -0
  96. data/lib/device_tracker/views/devices/users.erb +14 -0
  97. data/lib/device_tracker/views/emails/new_password.erb +17 -0
  98. data/lib/device_tracker/views/emails/password_reset.erb +18 -0
  99. data/lib/device_tracker/views/emails/registration.erb +16 -0
  100. data/lib/device_tracker/views/emails/reminder.erb +15 -0
  101. data/lib/device_tracker/views/emails/verification.erb +18 -0
  102. data/lib/device_tracker/views/forgot_password.erb +6 -0
  103. data/lib/device_tracker/views/index.erb +38 -0
  104. data/lib/device_tracker/views/layout.erb +8 -0
  105. data/lib/device_tracker/views/login.erb +14 -0
  106. data/lib/device_tracker/views/operating_system/operating_systems.json.jbuilder +9 -0
  107. data/lib/device_tracker/views/os/manage.erb +38 -0
  108. data/lib/device_tracker/views/transactions/_transactions_list.erb +18 -0
  109. data/lib/device_tracker/views/transactions/index.erb +3 -0
  110. data/lib/device_tracker/views/users/edit.erb +9 -0
  111. data/lib/device_tracker/views/users/manage.erb +31 -0
  112. data/lib/device_tracker/views/users/new.erb +7 -0
  113. metadata +505 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5d723cc5a90dabf8893383431a55eadc23c59414
4
+ data.tar.gz: 7e9d8ed84ab3d673f621b1ff3af1fd21df0eed34
5
+ SHA512:
6
+ metadata.gz: 5eff08a5da86eb468b2f88698ee2abdb20c27f2577fd0223211a292121440888272bed0ec12c03af5bb4019b052695c55b846c9e4ba8ae10a41fb7145347eced
7
+ data.tar.gz: 68c74502043868dd62ccdcb41cd216d44c6e3918107fb4565f55c6f6c05516ab47c61acc0398f7a2a4a10ac24e77101be6c718dbddf787a9555e988ccaf2f7f1
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ .idea/*
2
+ *.sqlite3
3
+ *.sqlite
4
+ src/bin
5
+ backup.sql
6
+ /.bundle/
7
+ /.yardoc
8
+ /Gemfile.lock
9
+ /_yardoc/
10
+ /coverage/
11
+ /doc/
12
+ /pkg/
13
+ /spec/reports/
14
+ /tmp/
15
+ capybara-*
16
+ development.json
17
+ .byebug_history
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format NyanCatMusicFormatter
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ AllCops:
2
+ Exclude:
3
+ - lib/db/schema.rb
4
+ - lib/device_tracker/db/**/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in device_tracker.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
8
+ task :debug do
9
+ sh 'bundle exec exe/device_tracker'
10
+ end
data/Readme.md ADDED
@@ -0,0 +1,32 @@
1
+ [![Gem Version](https://badge.fury.io/rb/device-tracker.svg)](https://badge.fury.io/rb/device-tracker)
2
+ # Device Tracker
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'device_tracker'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install device_tracker
19
+
20
+ ## Usage
21
+
22
+ TODO: Write usage instructions here
23
+
24
+ ## Development
25
+
26
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
27
+
28
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
29
+
30
+ ## Contributing
31
+
32
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bbc/device-tracker.
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'device_tracker'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,63 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'device_tracker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'device_tracker'
8
+ spec.version = DeviceTracker::VERSION
9
+ spec.authors = ['James Ruston', 'John Crossley']
10
+ spec.email = ['james.ruston@bbc.com', 'john.crossley@bbc.co.uk']
11
+
12
+ spec.required_ruby_version = '~> 2.0'
13
+
14
+ spec.summary = 'A web app for managing mobile devices'
15
+ spec.description = <<-EOF
16
+ Keep track of your devices.
17
+ Features: - User registration/login/validation
18
+ - User levels (normal/admin)
19
+ - Checkout devices
20
+ - Return devices
21
+ - Assign devices to someone (Admin only)
22
+ - Validate a user (Admin only)
23
+ - Search devices
24
+ - Keep track of number of times devices used
25
+ - Manage OS versions
26
+ - Send reminders when devices have been out for period of time
27
+ - Password reset
28
+ EOF
29
+ spec.homepage = 'https://github.com/bbc/device-tracker'
30
+
31
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
32
+ f.match(%r{^(test|spec|features)/})
33
+ end
34
+ spec.bindir = 'exe'
35
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ['lib']
37
+
38
+ spec.add_development_dependency 'bundler', '~> 1.7'
39
+ spec.add_development_dependency 'rspec', '~> 3.4'
40
+ spec.add_development_dependency 'shotgun', '~> 0.9'
41
+ spec.add_development_dependency 'byebug', '~> 8.1'
42
+ spec.add_development_dependency 'nyan-cat-formatter'
43
+ spec.add_development_dependency 'capybara'
44
+ spec.add_development_dependency 'poltergeist'
45
+ spec.add_development_dependency 'database_cleaner'
46
+ spec.add_development_dependency 'factory_girl'
47
+
48
+ spec.add_dependency 'sinatra', '~> 1.4'
49
+ spec.add_dependency 'activerecord', '~> 4.0'
50
+ spec.add_dependency 'sinatra-activerecord', '~> 2.0'
51
+ spec.add_dependency 'bcrypt', '~> 3.1.7'
52
+ spec.add_dependency 'json', '~> 1.7'
53
+ spec.add_dependency 'sinatra-contrib', '~> 1.4'
54
+ spec.add_dependency 'sinatra-partial', '~> 0.4'
55
+ spec.add_dependency 'sinatra-flash', '~> 0.3'
56
+ spec.add_dependency 'thin', '~> 1.6'
57
+ spec.add_dependency 'rake', '~> 10.4'
58
+ spec.add_dependency 'sqlite3', '~> 1.3'
59
+ spec.add_dependency 'pony', '~> 1.11'
60
+ spec.add_dependency 'mysql2', '~> 0.3.20'
61
+ spec.add_dependency 'json-schema', '~> 2.5'
62
+ spec.add_dependency 'faker'
63
+ end
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'device_tracker/device_tracker'
4
+ require 'optparse'
5
+ require 'json-schema'
6
+ require 'json'
7
+
8
+ config_path = './development.json'
9
+
10
+ OptionParser.new do |opts|
11
+ opts.banner = 'Usage: device_tracker [configuration]'
12
+
13
+ opts.on('-c', '--config [PATH]', String, 'Path to the config file.') do |path|
14
+ puts path
15
+ config_path = path
16
+ end
17
+
18
+ begin
19
+ opts.parse! ARGV
20
+ rescue OptionParser::InvalidOption
21
+ puts 'Invalid options supplied, use `device_tracker -h` help.'
22
+ end
23
+ end
24
+
25
+ puts config_path
26
+
27
+ unless File.exist?(config_path)
28
+ puts "File not found at #{File.expand_path(config_path)}"
29
+ exit 1
30
+ end
31
+
32
+ json = File.read(config_path)
33
+
34
+ errors = JSON::Validator.fully_validate(
35
+ File.expand_path('../../lib/device_tracker/config-schema.json', __FILE__),
36
+ json
37
+ )
38
+
39
+ unless errors.empty?
40
+ puts errors
41
+ exit 1
42
+ end
43
+
44
+ config = JSON.parse(json)
45
+
46
+ set :database, config['database']
47
+
48
+ config['email'].symbolize_keys!
49
+ pony_options = {}
50
+
51
+ # HACK: This needs cleaning at some point
52
+ config['email'].each do |key, value|
53
+ if key == :via
54
+ pony_options[key] = value.to_sym if key == :via
55
+ else
56
+ if key == :via_options
57
+ pony_options[key] = value.symbolize_keys!
58
+ pony_options[:via_options].each do |i_key, i_val|
59
+ if i_key == :authentication
60
+ pony_options[:via_options][i_key] = i_val.to_sym
61
+ else
62
+ pony_options[:via_options][i_key] = i_val
63
+ end
64
+ end
65
+ else
66
+ pony_options[key] = value
67
+ end
68
+ end
69
+ end
70
+
71
+ require_relative '../lib/device_tracker/dependencies'
72
+
73
+ Pony.options = pony_options
74
+
75
+ DeviceTracker::ApplicationController.set :session_secret,
76
+ config['session_secret']
77
+ DeviceTracker::ApplicationController.set :google_maps_api_key,
78
+ config['google_maps_api_key']
79
+ port = config['port'] || '3000'
80
+ host = config['host'] || '127.0.0.1'
81
+
82
+ ActiveRecord::Migrator.migrate(
83
+ File.expand_path('../../lib/device_tracker/db/migrate', __FILE__)
84
+ )
85
+
86
+
87
+ require_relative '../lib/device_tracker/db/seeds'
88
+
89
+ DeviceTracker::Seed.seed(config['admin'])
90
+
91
+ DeviceTracker.start(host, port)
@@ -0,0 +1,22 @@
1
+ require_relative 'dependencies'
2
+ require 'rack'
3
+
4
+ module DeviceTracker
5
+ # :nodoc:
6
+ class App
7
+ def initialize
8
+ @app = Rack::Builder.new do
9
+ map('/heartbeats') { run HeartbeatController }
10
+ map('/transactions') { run TransactionsController }
11
+ map('/users') { run UsersController }
12
+ map('/devices') { run DevicesController }
13
+ map('/os') { run OSController }
14
+ map('/') { run ApplicationController }
15
+ end
16
+ end
17
+
18
+ def call(env)
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,111 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "id": "http://jsonschema.net",
4
+ "type": "object",
5
+ "properties": {
6
+ "database": {
7
+ "id": "http://jsonschema.net/database",
8
+ "type": "object",
9
+ "properties": {
10
+ "adapter": {
11
+ "id": "http://jsonschema.net/database/adapter",
12
+ "type": "string"
13
+ }
14
+ },
15
+ "required": [
16
+ "adapter"
17
+ ]
18
+ },
19
+ "email": {
20
+ "id": "http://jsonschema.net/email",
21
+ "type": "object",
22
+ "properties": {
23
+ "from": {
24
+ "id": "http://jsonschema.net/email/from",
25
+ "type": "string"
26
+ },
27
+ "via": {
28
+ "id": "http://jsonschema.net/email/via",
29
+ "type": "string"
30
+ },
31
+ "via_options": {
32
+ "id": "http://jsonschema.net/email/via_options",
33
+ "type": "object",
34
+ "properties": {
35
+ "address": {
36
+ "id": "http://jsonschema.net/email/via_options/address",
37
+ "type": "string"
38
+ },
39
+ "port": {
40
+ "id": "http://jsonschema.net/email/via_options/port",
41
+ "type": "string"
42
+ },
43
+ "enable_starttls_auto": {
44
+ "id": "http://jsonschema.net/email/via_options/enable_starttls_auto",
45
+ "type": "boolean"
46
+ },
47
+ "user_name": {
48
+ "id": "http://jsonschema.net/email/via_options/user_name",
49
+ "type": "string"
50
+ },
51
+ "password": {
52
+ "id": "http://jsonschema.net/email/via_options/password",
53
+ "type": "string"
54
+ },
55
+ "authentication": {
56
+ "id": "http://jsonschema.net/email/via_options/authentication",
57
+ "type": "string"
58
+ },
59
+ "domain": {
60
+ "id": "http://jsonschema.net/email/via_options/domain",
61
+ "type": "string"
62
+ }
63
+ }
64
+ }
65
+ }
66
+ },
67
+ "session_secret": {
68
+ "id": "http://jsonschema.net/session_secret",
69
+ "type": "string"
70
+ },
71
+ "google_maps_api_key": {
72
+ "id": "http://jsonschema.net/google_maps_api_key",
73
+ "type": "string"
74
+ },
75
+ "host": {
76
+ "id": "http://jsonschema.net/host",
77
+ "type": "string"
78
+ },
79
+ "port": {
80
+ "id": "http://jsonschema.net/port",
81
+ "type": "string"
82
+ },
83
+ "admin": {
84
+ "id": "http://jsonschema.net/admin",
85
+ "type": "object",
86
+ "properties": {
87
+ "name": {
88
+ "id": "http://jsonschema.net/admin/name",
89
+ "type": "string"
90
+ },
91
+ "email": {
92
+ "id": "http://jsonschema.net/admin/email",
93
+ "type": "string"
94
+ },
95
+ "password": {
96
+ "id": "http://jsonschema.net/admin/password",
97
+ "type": "string"
98
+ }
99
+ }
100
+ }
101
+ },
102
+ "required": [
103
+ "database",
104
+ "email",
105
+ "session_secret",
106
+ "google_maps_api_key",
107
+ "host",
108
+ "port",
109
+ "admin"
110
+ ]
111
+ }
@@ -0,0 +1,9 @@
1
+ require './dependencies'
2
+
3
+ # map the controllers to routes
4
+ map('/heartbeats') { run HeartbeatController }
5
+ map('/transactions') { run TransactionsController }
6
+ map('/users') { run UsersController }
7
+ map('/devices') { run DevicesController }
8
+ map('/os') { run OSController }
9
+ map('/') { run ApplicationController }
@@ -0,0 +1,226 @@
1
+ module DeviceTracker
2
+ # :nodoc:
3
+ class ApplicationController < Sinatra::Base
4
+ helpers ApplicationHelper
5
+ helpers UserHelper
6
+
7
+ register Sinatra::ActiveRecordExtension
8
+ register Sinatra::Partial
9
+ register Sinatra::Flash
10
+
11
+ enable :sessions
12
+ enable :partial_underscores
13
+
14
+ set :views, File.expand_path('../../views', __FILE__)
15
+ set :public_dir, File.expand_path('../../public', __FILE__)
16
+ set :partial_template_engine, :erb
17
+
18
+ set :email_path, File.expand_path('../../views/emails/', __FILE__)
19
+
20
+ use Rack::MethodOverride
21
+
22
+ configure :development do
23
+ require 'byebug'
24
+ end
25
+
26
+ configure :test do
27
+ set database: {
28
+ adapter: 'sqlite3',
29
+ database: File.expand_path('../../db/test.sqlite', __FILE__)
30
+ }
31
+ end
32
+
33
+ configure :production, :development do
34
+ enable :logging
35
+ end
36
+
37
+ not_found do
38
+ @administrators = User.where(is_verified: true, is_admin: true)
39
+ erb :"404"
40
+ end
41
+
42
+ get '/version' do
43
+ halt 200,
44
+ error: false,
45
+ version: DeviceTracker::VERSION
46
+ end
47
+
48
+ get '/' do
49
+ @devices = Device.where(available: false)
50
+ .order(checked_out_since: :desc).limit(10)
51
+
52
+ erb :index, devices: @devices
53
+ end
54
+
55
+ get '/forgot-password' do
56
+ if !params[:user_id].nil? && !params[:password_reset].nil?
57
+
58
+ # Check to see if the user_id matches the password_reset
59
+
60
+ @user = User.where(id: params[:user_id],
61
+ reset_code: params[:password_reset]).first
62
+
63
+ if @user.nil?
64
+ create_flash 'warning',
65
+ ['Hmm, that\'s not right. Did you click a valid link?']
66
+ redirect '/'
67
+ end
68
+
69
+ # Reset that back
70
+ @user.reset_code = nil
71
+
72
+ @new_password = generate_activation_code 12
73
+
74
+ @user.password = @new_password
75
+
76
+ @user.save
77
+
78
+ body = ERB.new(
79
+ File.read(settings.email_path + '/new_password.erb')
80
+ ).result(binding)
81
+
82
+ send_email(
83
+ to: @user.email,
84
+ from: 'no-reply@device-tracker',
85
+ subject: 'New password | Device Tracker',
86
+ body: body
87
+ )
88
+
89
+ create_flash 'success',
90
+ ["Your new password has been emailed to #{@user.email}"]
91
+ redirect '/login'
92
+
93
+ else
94
+ erb :forgot_password
95
+ end
96
+ end
97
+
98
+ put '/:device_id/found' do |device_id|
99
+ if Device.exists?(device_id)
100
+
101
+ user = logged_in_user
102
+
103
+ device = Device.find(device_id)
104
+ device.missing = false
105
+ device.save
106
+
107
+ report_transaction(
108
+ "#{user[:email]} reported #{device.full_name} as found",
109
+ Transaction.found, device
110
+ )
111
+
112
+ create_flash 'success',
113
+ ['The device has been returned successfully!']
114
+ redirect back
115
+ else
116
+ fail Siatra::NotFound
117
+ end
118
+ end
119
+
120
+ put '/:device_id/missing' do |device_id|
121
+ if Device.exists?(device_id)
122
+
123
+ user = logged_in_user
124
+
125
+ device = Device.find(device_id)
126
+ device.missing = true
127
+ device.save
128
+
129
+ report_transaction(
130
+ "#{user[:email]} reported #{device.full_name} missing",
131
+ Transaction.missing,
132
+ device
133
+ )
134
+
135
+ create_flash 'success', ['The device has been reported missing!']
136
+ redirect back
137
+ else
138
+ fail Sinatra::NotFound
139
+ end
140
+ end
141
+
142
+ post '/forgot-password' do
143
+ # user = User.find(params[:email])
144
+ if User.exists?(email: params[:email])
145
+
146
+ # Generate a random string
147
+ random_string = generate_activation_code 24
148
+
149
+ @user = User.find_by_email(params[:email])
150
+ @user.reset_code = random_string
151
+ @user.save
152
+
153
+ @reset_url = request.url +
154
+ "?user_id=#{@user.id}&password_reset=" + random_string
155
+
156
+ body = ERB.new(
157
+ File.read(settings.email_path + '/password_reset.erb')
158
+ ).result(binding)
159
+
160
+ # Email that user with the link
161
+ # /password-reset?user_id=1&reset_code=MWAZ9JT9WKRP7RPTF3RHEG9J
162
+ send_email(
163
+ to: @user.email,
164
+ from: 'no-reply@device-tracker',
165
+ subject: 'Password Reset | Device Tracker',
166
+ body: body
167
+ )
168
+
169
+ # Validate the link
170
+ # Send the user a new password
171
+
172
+ create_flash 'success',
173
+ ["A password reset link has been sent to #{@user.email}"]
174
+ redirect back
175
+
176
+ else
177
+ create_flash 'warning',
178
+ ["Sorry, but the email #{params[:email]} doesn't exist."]
179
+ redirect back
180
+ end
181
+ end
182
+
183
+ get '/logout' do
184
+ session[:user] = nil
185
+ redirect to('/')
186
+ end
187
+
188
+ get '/login' do
189
+ erb :login
190
+ end
191
+
192
+ post '/login' do
193
+ # Parse the form
194
+ email = params[:user][:email]
195
+ password = params[:user][:password]
196
+
197
+ if email.empty? || password.empty?
198
+ create_flash 'warning', ['Please supply a username and or password']
199
+ redirect back
200
+ end
201
+
202
+ flash[:email] = email
203
+
204
+ user = User.find_by_email(email)
205
+
206
+ if user.nil? || !user.authenticate(password)
207
+ flash_and_go_back 'warning',
208
+ ['Invalid username and or password entered.']
209
+ end
210
+
211
+ unless user.is_verified
212
+ flash_and_go_back 'warning', ['Your account is waiting verification.']
213
+ end
214
+
215
+ session[:user] = {
216
+ id: user.id,
217
+ name: user.name,
218
+ email: user.email,
219
+ is_admin: user.is_admin,
220
+ is_verified: user.is_verified
221
+ }
222
+
223
+ redirect to("devices/users/#{session[:user][:id]}")
224
+ end
225
+ end
226
+ end