volt 0.8.21 → 0.8.22.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +15 -10
  3. data/CHANGELOG.md +8 -0
  4. data/Gemfile +7 -33
  5. data/Readme.md +2 -0
  6. data/VERSION +1 -1
  7. data/app/volt/assets/js/{setImmediate.js → volt_js_polyfills.js} +14 -0
  8. data/app/volt/models/user.rb +21 -26
  9. data/app/volt/tasks/live_query/data_store.rb +4 -0
  10. data/app/volt/tasks/store_tasks.rb +8 -11
  11. data/app/volt/tasks/user_tasks.rb +18 -17
  12. data/lib/volt.rb +7 -1
  13. data/lib/volt/cli.rb +2 -0
  14. data/lib/volt/config.rb +69 -29
  15. data/lib/volt/extra_core/object.rb +8 -0
  16. data/lib/volt/models/model_hash_behaviour.rb +26 -6
  17. data/lib/volt/models/persistors/model_store.rb +1 -2
  18. data/lib/volt/models/validations.rb +18 -9
  19. data/lib/volt/models/validators/length_validator.rb +1 -1
  20. data/lib/volt/models/validators/presence_validator.rb +1 -1
  21. data/lib/volt/models/validators/unique_validator.rb +1 -1
  22. data/lib/volt/page/bindings/template_binding.rb +2 -1
  23. data/lib/volt/page/page.rb +7 -2
  24. data/lib/volt/page/sub_context.rb +8 -4
  25. data/lib/volt/page/targets/base_section.rb +1 -1
  26. data/lib/volt/page/targets/dom_template.rb +1 -1
  27. data/lib/volt/server.rb +3 -2
  28. data/lib/volt/server/html_parser/view_scope.rb +1 -0
  29. data/lib/volt/server/rack/component_code.rb +8 -1
  30. data/lib/volt/server/rack/component_paths.rb +2 -1
  31. data/lib/volt/server/rack/quiet_common_logger.rb +34 -0
  32. data/lib/volt/spec/setup.rb +30 -1
  33. data/lib/volt/utils/generic_pool.rb +4 -0
  34. data/lib/volt/volt/users.rb +18 -0
  35. data/spec/apps/kitchen_sink/Gemfile +3 -0
  36. data/spec/apps/kitchen_sink/app/main/config/dependencies.rb +6 -0
  37. data/spec/apps/kitchen_sink/app/main/config/routes.rb +5 -1
  38. data/spec/apps/kitchen_sink/app/main/models/user.rb +2 -0
  39. data/spec/apps/kitchen_sink/app/main/views/main/main.html +1 -1
  40. data/spec/apps/kitchen_sink/{public → config/base}/index.html +0 -0
  41. data/spec/integration/bindings_spec.rb +1 -1
  42. data/spec/integration/cookies_spec.rb +1 -1
  43. data/spec/integration/flash_spec.rb +3 -2
  44. data/spec/integration/list_spec.rb +1 -1
  45. data/spec/integration/templates_spec.rb +1 -1
  46. data/spec/integration/url_spec.rb +1 -1
  47. data/spec/integration/user_spec.rb +60 -0
  48. data/spec/models/model_spec.rb +0 -1
  49. data/spec/page/bindings/template_binding_spec.rb +0 -4
  50. data/spec/server/rack/asset_files_spec.rb +1 -1
  51. data/spec/spec_helper.rb +5 -0
  52. data/templates/component/tasks/.empty_directory +0 -0
  53. data/templates/newgem/app/newgem/views/main/{main.html → index.html} +0 -0
  54. data/templates/project/Gemfile.tt +0 -11
  55. data/templates/project/app/main/config/routes.rb +5 -0
  56. data/templates/project/app/main/tasks/.empty_directory +0 -0
  57. data/templates/project/app/main/views/main/main.html.tt +1 -0
  58. data/templates/project/config/app.rb.tt +8 -3
  59. data/volt.gemspec +4 -6
  60. metadata +58 -12
  61. data/spec/apps/kitchen_sink/app/main/controllers/users_test_controller.rb +0 -27
  62. data/spec/apps/kitchen_sink/app/main/views/users_test/index.html +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a638546992d567cf43d90ee011ecf7f30fa5880f
4
- data.tar.gz: c9d05f29f59cd52ff900ae25e0176536fc4842b6
3
+ metadata.gz: 710bbd40c4e0f2a2ee402f97df5d82d1a6a57704
4
+ data.tar.gz: d21e4a67eb50b440710ab0abbd20f5c4b90da1ca
5
5
  SHA512:
6
- metadata.gz: 4bb40aeba3bb1ffb8d680dc636ab2f4f0c2dfd64ee408994aa502f018a04729a8cd357b55c526c60ad7855b9c91f4635c75510abd445776d67a4e429e6217f37
7
- data.tar.gz: 72c91c7a5390e3c7bda4e02861dc108504b56422f36a1d787ec47abcc22ed754ccfb323ccab08282a9d2b8fa2fbcaac9f670a88116edee581bcde044598c9a0a
6
+ metadata.gz: 1b544c000e50d4760a799bb63ae4a90a772b2dddff295063c93316dc09335c6c7664b97cc05d77d361dfb587298b90800ad62608a567e224179b9e10e5bb3034
7
+ data.tar.gz: 63cca01208dd44244a9aeae62319c1187e8bd393846e1f904277a7f0ee021eecfe8d6573bfce15c85b66c36179eced0396e19e09a3eaeba89fd821174a6f6aef
data/.travis.yml CHANGED
@@ -1,16 +1,21 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "2.1.0"
4
- - "2.1.1"
5
- - "2.1.2"
6
- - "2.1.3"
7
- # - jruby-19mode # JRuby in 1.9 mode
8
- # - rbx
3
+ - 2.1.0
4
+ - 2.1.1
5
+ - 2.1.2
6
+ - 2.1.3
7
+ env:
8
+ global:
9
+ - secure: W03bt+hqLkAenymipqADIuRGZMiqu/sKx+9PXJJzCy0qAgmKs/PhPpHRpGpSmaYvVQQuiWX/rsw7xWXc2CHDJSp5aInd693xhJuSKXmnUp00r14/io+VWI9LE0lWjx4qdb6YQhdBTaxJB0+1sHDwU088yWBNnri/KwU4UlUgO5M=
10
+ - secure: X95q9DUVJRLIoxd116xEbi/3xL85XiGbWdz0p5z/UawShQalMHxLfPNdU9u5gyw99LrgxTdPsJOTps8hB3vhzp8qIegrM8i2AICcicXC1QDOWi7McXSH9SBmE1AjhlyE/PLLHwLDeqfvwNMPAOrDH1GOisQp505D7SSXUZ9m0GI=
11
+ matrix:
12
+ - NO_BROWSER=true
13
+ - BROWSER=sauce OS="Windows 8" USE_BROWSER="Firefox" VERSION="33"
9
14
  script: bundle exec rake
10
15
  notifications:
11
16
  webhooks:
12
17
  urls:
13
- - https://webhooks.gitter.im/e/046f551739ef8cf19b8c
14
- on_success: change # options: [always|never|change] default: always
15
- on_failure: always # options: [always|never|change] default: always
16
- on_start: false # default: false
18
+ - https://webhooks.gitter.im/e/046f551739ef8cf19b8c
19
+ on_success: change
20
+ on_failure: always
21
+ on_start: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.8.22 - 2014-...
4
+ ### Added
5
+ - Volt.config is now accessable from the client.
6
+
7
+ ## 0.8.21 - 2014-11-05
8
+ ### Changed
9
+ - fix merge conflict
10
+
3
11
  ## 0.8.20 - 2014-11-05
4
12
  ### Changed
5
13
  - fix secure random bug from 0.8.19 :-)
data/Gemfile CHANGED
@@ -2,35 +2,6 @@ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- # gem 'rspec', '3.0.0.beta1'
6
- # gem 'opal', git: 'https://github.com/opal/opal.git'
7
- # gem 'opal-jquery', :git => 'https://github.com/opal/opal-jquery.git'
8
-
9
- #---------------------
10
- # Needed at the moment
11
- gem 'volt-sockjs', require: false, platforms: :mri
12
-
13
- # gem 'thor'
14
-
15
- # gem 'rack'
16
- # gem 'sprockets'
17
- # gem 'sprockets-sass'
18
- # gem 'sass'
19
-
20
- # gem 'mongo', require: false
21
- # gem 'pry', require: false
22
- # gem 'thin', require: false, platforms: :mri
23
-
24
- # Json parsing with multi_json, et al
25
- # gem 'multi_json'
26
- # gem 'oj', :platforms => :mri, :require => false
27
- # gem 'jrjackson', :platforms => :jruby, :require => false
28
-
29
- # gem 'rake', '10.0.4'
30
-
31
- # # Needed to get opal to work on rbx
32
- # gem 'racc', platforms: :rbx
33
-
34
5
  group :development do
35
6
  # For testing the kitchen sink app
36
7
  # Twitter bootstrap
@@ -39,11 +10,14 @@ group :development do
39
10
  # Simple theme for bootstrap, remove to theme yourself.
40
11
  gem 'volt-bootstrap-jumbotron-theme'
41
12
 
13
+ # For testing
14
+ gem 'volt-fields'
15
+
16
+ # For testing
17
+ gem 'volt-user-templates'
18
+
19
+ # For running rubocop
42
20
  gem 'rubocop', require: false
43
- # gem 'guard', '2.0.1' # bug in current guard
44
- # gem 'guard-rspec'
45
- # gem 'opal-rspec', '0.3.0.beta2'#, git: 'https://github.com/adambeynon/opal-rspec.git'
46
- # gem 'yard', require: false
47
21
  end
48
22
 
49
23
  group :development, :test do
data/Readme.md CHANGED
@@ -35,3 +35,5 @@ Read the [full docs on Volt here](http://voltframework.com/docs)
35
35
  You want to contribute? Great! Thanks for being awesome! At the moment, we have a big internal todo list, hop on https://gitter.im/voltrb/volt so we don't duplicate work. Pull requests are always welcome, but asking about helping on gitter should save some duplication.
36
36
 
37
37
  [![Pledgie](https://pledgie.com/campaigns/26731.png?skin_name=chrome)](https://pledgie.com/campaigns/26731)
38
+
39
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.21
1
+ 0.8.22.beta1
@@ -1,3 +1,17 @@
1
+ // For phantomjs
2
+
3
+ // Bind
4
+ if (!Function.prototype.bind) {
5
+ Function.prototype.bind = function (scope) {
6
+ var fn = this;
7
+ return function () {
8
+ return fn.apply(scope);
9
+ };
10
+ };
11
+ }
12
+
13
+
14
+ // setImmediate
1
15
  (function (global, undefined) {
2
16
  "use strict";
3
17
 
@@ -2,37 +2,32 @@ if RUBY_PLATFORM != 'opal'
2
2
  require 'bcrypt'
3
3
  end
4
4
 
5
- class User < Volt::Model
6
- validate :username, unique: true, length: 8
7
- if RUBY_PLATFORM == 'opal'
8
- # Don't validate on the server
9
- validate :password, length: 8
10
- end
11
-
12
- def password=(val)
13
- if Volt.server?
14
- # on the server, we bcrypt the password and store the result
15
- self._hashed_password = BCrypt::Password.create(val)
16
- else
17
- self._password = val
5
+ module Volt
6
+ class User < Model
7
+ # returns true if the user configured using the username
8
+ def self.login_field
9
+ if Volt.config.public.try(:auth).try(:use_username)
10
+ :username
11
+ else
12
+ :email
13
+ end
18
14
  end
19
- end
20
15
 
21
- # Login the user, return a promise for success
22
- def self.login(username, password)
23
- puts "Login now"
24
- UserTasks.login(username, password).then do |result|
25
- puts "Got: #{result.inspect}"
16
+ validate login_field, unique: true, length: 8
26
17
 
27
- # Assign the user_id cookie for the user
28
- $page.cookies._user_id = result
18
+ if RUBY_PLATFORM == 'opal'
19
+ # Don't validate on the server
20
+ validate :password, length: 8
21
+ end
29
22
 
30
- # Pass nil back
31
- nil
23
+ def password=(val)
24
+ if Volt.server?
25
+ # on the server, we bcrypt the password and store the result
26
+ self._hashed_password = BCrypt::Password.create(val)
27
+ else
28
+ self._password = val
29
+ end
32
30
  end
33
- end
34
31
 
35
- def self.logout
36
- $page.cookies.delete(:user_id)
37
32
  end
38
33
  end
@@ -18,4 +18,8 @@ class DataStore
18
18
 
19
19
  return cursor.to_a
20
20
  end
21
+
22
+ def drop_database
23
+ db.connection.drop_database(Volt.config.db_name)
24
+ end
21
25
  end
@@ -12,20 +12,17 @@ class StoreTasks < Volt::TaskHandler
12
12
  end
13
13
 
14
14
  def load_model(collection, path, data)
15
- puts "Load Model: #{path.inspect}"
16
15
  model_name = collection.singularize.camelize
17
16
 
18
- # TODO: Security check to make sure we have a valid model
19
- # and don't load classes we shouldn't
20
- begin
21
- model_class = Object.send(:const_get, model_name)
22
- rescue NameError => e
23
- model_class = Volt::Model
24
- end
17
+ # Fetch the model
18
+ collection = store.send(:"_#{path[-2]}")
19
+
20
+ # See if the model has already been made
21
+ model = collection.find_one({_id: data[:_id]})
22
+
23
+ # Otherwise assign to the collection
24
+ model ||= collection
25
25
 
26
- # Load the model, use the Store persistor and set the path
27
- model = model_class.new({}, persistor: Volt::Persistors::StoreFactory.new(nil), path: path)
28
- model.persistor.change_state_to(:loaded)
29
26
 
30
27
  # Create a buffer
31
28
  buffer = model.buffer
@@ -1,29 +1,30 @@
1
1
  class UserTasks < Volt::TaskHandler
2
- # Login a user, takes a username and password
3
2
 
4
- def login(username, password)
5
- puts "META: " + Thread.current['meta'].inspect
3
+ # Login a user, takes a login and password. Login can be either a username or an e-mail
4
+ # based on Volt.config.public.auth.use_username
5
+ def login(login, password)
6
+ query = {User.login_field => login}
6
7
 
7
- if Volt.user
8
- puts "USER: " + Volt.user._name
9
- end
10
-
11
- return store._users.find(username: username).then do |users|
8
+ return store._users.find(query).then do |users|
12
9
  user = users.first
13
10
 
14
- match_pass = BCrypt::Password.new(user._hashed_password)
15
- if match_pass == password
16
- raise "app_secret is not configured" unless Volt.config.app_secret
11
+ if user
12
+ match_pass = BCrypt::Password.new(user._hashed_password)
13
+ if match_pass == password
14
+ raise "app_secret is not configured" unless Volt.config.app_secret
17
15
 
18
- # TODO: returning here should be possible, but causes some issues
16
+ # TODO: returning here should be possible, but causes some issues
19
17
 
20
- # Salt the user id with the app_secret so the end user can't tamper with the cookie
21
- signature = BCrypt::Password.create("#{Volt.config.app_secret}::#{user._id}")
18
+ # Salt the user id with the app_secret so the end user can't tamper with the cookie
19
+ signature = BCrypt::Password.create("#{Volt.config.app_secret}::#{user._id}")
22
20
 
23
- # Return user_id:hash on user id
24
- next "#{user._id}:#{signature}"
21
+ # Return user_id:hash on user id
22
+ next "#{user._id}:#{signature}"
23
+ else
24
+ raise "Password did not match"
25
+ end
25
26
  else
26
- raise "Password did not match"
27
+ raise "User could not be found"
27
28
  end
28
29
  end
29
30
  end
data/lib/volt.rb CHANGED
@@ -2,11 +2,12 @@ require 'volt/volt/environment'
2
2
  require 'volt/extra_core/extra_core'
3
3
  require 'volt/reactive/computation'
4
4
  require 'volt/reactive/dependency'
5
+ require 'volt/config'
5
6
  if RUBY_PLATFORM == 'opal'
6
7
  else
7
- require 'volt/config'
8
8
  require 'volt/data_stores/data_store'
9
9
  end
10
+ require 'volt/volt/users'
10
11
 
11
12
  module Volt
12
13
  @in_browser = if RUBY_PLATFORM == 'opal'
@@ -83,6 +84,11 @@ module Volt
83
84
  end
84
85
  end
85
86
 
87
+ # True if the user is logged in and the user is loaded
88
+ def user?
89
+ !!user
90
+ end
91
+
86
92
  # Return the current user.
87
93
  def user
88
94
  user_id = self.user_id
data/lib/volt/cli.rb CHANGED
@@ -1,4 +1,6 @@
1
+ # Load in the gemfile
1
2
  require 'bundler/setup'
3
+
2
4
  require 'thor'
3
5
  require 'volt/extra_core/extra_core'
4
6
  require 'volt/cli/generate'
data/lib/volt/config.rb CHANGED
@@ -1,42 +1,82 @@
1
1
  # Config lets a user set global config options for Volt.
2
- require 'configurations'
3
- module Volt
4
- include Configurations
5
-
6
- class << self
7
- def defaults
8
- app_name = File.basename(Dir.pwd)
9
- {
10
- app_name: app_name,
11
- db_name: ENV['DB_NAME'] || (app_name + '_' + Volt.env.to_s),
12
- db_host: ENV['DB_HOST'] || 'localhost',
13
- db_port: (ENV['DB_PORT'] || 27_017).to_i,
14
- db_driver: ENV['DB_DRIVER'] || 'mongo',
15
- }
2
+ # The hash is setup on the server, then passed to the client on initial page render.
3
+ if RUBY_PLATFORM == 'opal'
4
+ require 'ostruct'
5
+
6
+ # TODO: Temporary fix for missing on OpenStruct in opal
7
+ class OpenStruct
8
+ def respond_to?(method_name)
9
+ @table.key?(method_name) || super
16
10
  end
11
+ end
17
12
 
18
- # Resets the configuration to the default (empty hash)
19
- def reset_config!
20
- self.configure do |c|
21
- c.from_h(defaults)
13
+ module Volt
14
+ class << self
15
+ # Returns the config
16
+ def config
17
+ @config
22
18
  end
23
- end
24
19
 
25
- # Load in all .rb files in the config folder
26
- def run_files_in_config_folder
27
- Dir[Dir.pwd + '/config/*.rb'].each do |config_file|
28
- require(config_file)
20
+ # Called on page load to pass the backend config to the client
21
+ def setup_client_config(config_hash)
22
+ # Only Volt.config.public is passed from the server (for security reasons)
23
+ @config = wrap_config({public: config_hash})
29
24
  end
30
- end
31
25
 
32
- alias_method :setup, :configure
33
- alias_method :config, :configuration
34
- end
26
+ # Wraps the config hash in an OpenStruct so it can be accessed in the same way
27
+ # as the server side config.
28
+ def wrap_config(hash)
29
+ new_hash = {}
30
+
31
+ hash.each_pair do |key, value|
32
+ if value.is_a?(Hash)
33
+ new_hash[key] = wrap_config(value)
34
+ else
35
+ new_hash[key] = value
36
+ end
37
+ end
35
38
 
36
- configuration_defaults do |c|
37
- c.from_h(Volt.defaults)
39
+ OpenStruct.new(new_hash)
40
+ end
41
+ end
38
42
  end
43
+ else
44
+ require 'configurations'
45
+ module Volt
46
+ include Configurations
39
47
 
48
+ class << self
49
+ def defaults
50
+ app_name = File.basename(Dir.pwd)
51
+ {
52
+ app_name: app_name,
53
+ db_name: ENV['DB_NAME'] || (app_name + '_' + Volt.env.to_s),
54
+ db_host: ENV['DB_HOST'] || 'localhost',
55
+ db_port: (ENV['DB_PORT'] || 27_017).to_i,
56
+ db_driver: ENV['DB_DRIVER'] || 'mongo',
57
+ }
58
+ end
59
+
60
+ # Resets the configuration to the default (empty hash)
61
+ def reset_config!
62
+ self.configure do |c|
63
+ c.from_h(defaults)
64
+ end
65
+ end
66
+
67
+ # Load in all .rb files in the config folder
68
+ def run_files_in_config_folder
69
+ Dir[Volt.root + '/config/*.rb'].each do |config_file|
70
+ require(config_file)
71
+ end
72
+ end
40
73
 
74
+ alias_method :setup, :configure
75
+ alias_method :config, :configuration
76
+ end
41
77
 
78
+ configuration_defaults do |c|
79
+ c.from_h(Volt.defaults)
80
+ end
81
+ end
42
82
  end
@@ -32,4 +32,12 @@ class Object
32
32
  def deep_clone
33
33
  Marshal.load(Marshal.dump(self))
34
34
  end
35
+
36
+ def try(*a, &b)
37
+ if a.empty? && block_given?
38
+ yield self
39
+ else
40
+ public_send(*a, &b) if respond_to?(a.first)
41
+ end
42
+ end
35
43
  end