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.
- checksums.yaml +4 -4
- data/.travis.yml +15 -10
- data/CHANGELOG.md +8 -0
- data/Gemfile +7 -33
- data/Readme.md +2 -0
- data/VERSION +1 -1
- data/app/volt/assets/js/{setImmediate.js → volt_js_polyfills.js} +14 -0
- data/app/volt/models/user.rb +21 -26
- data/app/volt/tasks/live_query/data_store.rb +4 -0
- data/app/volt/tasks/store_tasks.rb +8 -11
- data/app/volt/tasks/user_tasks.rb +18 -17
- data/lib/volt.rb +7 -1
- data/lib/volt/cli.rb +2 -0
- data/lib/volt/config.rb +69 -29
- data/lib/volt/extra_core/object.rb +8 -0
- data/lib/volt/models/model_hash_behaviour.rb +26 -6
- data/lib/volt/models/persistors/model_store.rb +1 -2
- data/lib/volt/models/validations.rb +18 -9
- data/lib/volt/models/validators/length_validator.rb +1 -1
- data/lib/volt/models/validators/presence_validator.rb +1 -1
- data/lib/volt/models/validators/unique_validator.rb +1 -1
- data/lib/volt/page/bindings/template_binding.rb +2 -1
- data/lib/volt/page/page.rb +7 -2
- data/lib/volt/page/sub_context.rb +8 -4
- data/lib/volt/page/targets/base_section.rb +1 -1
- data/lib/volt/page/targets/dom_template.rb +1 -1
- data/lib/volt/server.rb +3 -2
- data/lib/volt/server/html_parser/view_scope.rb +1 -0
- data/lib/volt/server/rack/component_code.rb +8 -1
- data/lib/volt/server/rack/component_paths.rb +2 -1
- data/lib/volt/server/rack/quiet_common_logger.rb +34 -0
- data/lib/volt/spec/setup.rb +30 -1
- data/lib/volt/utils/generic_pool.rb +4 -0
- data/lib/volt/volt/users.rb +18 -0
- data/spec/apps/kitchen_sink/Gemfile +3 -0
- data/spec/apps/kitchen_sink/app/main/config/dependencies.rb +6 -0
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +5 -1
- data/spec/apps/kitchen_sink/app/main/models/user.rb +2 -0
- data/spec/apps/kitchen_sink/app/main/views/main/main.html +1 -1
- data/spec/apps/kitchen_sink/{public → config/base}/index.html +0 -0
- data/spec/integration/bindings_spec.rb +1 -1
- data/spec/integration/cookies_spec.rb +1 -1
- data/spec/integration/flash_spec.rb +3 -2
- data/spec/integration/list_spec.rb +1 -1
- data/spec/integration/templates_spec.rb +1 -1
- data/spec/integration/url_spec.rb +1 -1
- data/spec/integration/user_spec.rb +60 -0
- data/spec/models/model_spec.rb +0 -1
- data/spec/page/bindings/template_binding_spec.rb +0 -4
- data/spec/server/rack/asset_files_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/templates/component/tasks/.empty_directory +0 -0
- data/templates/newgem/app/newgem/views/main/{main.html → index.html} +0 -0
- data/templates/project/Gemfile.tt +0 -11
- data/templates/project/app/main/config/routes.rb +5 -0
- data/templates/project/app/main/tasks/.empty_directory +0 -0
- data/templates/project/app/main/views/main/main.html.tt +1 -0
- data/templates/project/config/app.rb.tt +8 -3
- data/volt.gemspec +4 -6
- metadata +58 -12
- data/spec/apps/kitchen_sink/app/main/controllers/users_test_controller.rb +0 -27
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 710bbd40c4e0f2a2ee402f97df5d82d1a6a57704
|
4
|
+
data.tar.gz: d21e4a67eb50b440710ab0abbd20f5c4b90da1ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
14
|
-
on_success: change
|
15
|
-
on_failure: always
|
16
|
-
on_start: false
|
18
|
+
- https://webhooks.gitter.im/e/046f551739ef8cf19b8c
|
19
|
+
on_success: change
|
20
|
+
on_failure: always
|
21
|
+
on_start: false
|
data/CHANGELOG.md
CHANGED
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.
|
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
|
|
data/app/volt/models/user.rb
CHANGED
@@ -2,37 +2,32 @@ if RUBY_PLATFORM != 'opal'
|
|
2
2
|
require 'bcrypt'
|
3
3
|
end
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
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
|
-
|
28
|
-
|
18
|
+
if RUBY_PLATFORM == 'opal'
|
19
|
+
# Don't validate on the server
|
20
|
+
validate :password, length: 8
|
21
|
+
end
|
29
22
|
|
30
|
-
|
31
|
-
|
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
|
@@ -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
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
5
|
-
|
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
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
16
|
+
# TODO: returning here should be possible, but causes some issues
|
19
17
|
|
20
|
-
|
21
|
-
|
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
|
-
|
24
|
-
|
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 "
|
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
data/lib/volt/config.rb
CHANGED
@@ -1,42 +1,82 @@
|
|
1
1
|
# Config lets a user set global config options for Volt.
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
13
|
+
module Volt
|
14
|
+
class << self
|
15
|
+
# Returns the config
|
16
|
+
def config
|
17
|
+
@config
|
22
18
|
end
|
23
|
-
end
|
24
19
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
37
|
-
|
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
|