facebook_rails 0.0.1
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.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +38 -0
- data/app/controllers/facebook_rails_controller.rb +191 -0
- data/app/helpers/facebook_rails_helper.rb +90 -0
- data/lib/facebook_rails/engine.rb +48 -0
- data/lib/facebook_rails/version.rb +3 -0
- data/lib/facebook_rails.rb +17 -0
- data/lib/generators/facebook_rails/facebook_rails_generator.rb +11 -0
- data/lib/generators/facebook_rails/templates/facebook.yml +29 -0
- data/lib/tasks/facebook_rails_tasks.rake +4 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +56 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/facebook.yml +26 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +6 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/facebook_rails_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +156 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'FacebookRails'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
Bundler::GemHelper.install_tasks
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
|
30
|
+
Rake::TestTask.new(:test) do |t|
|
31
|
+
t.libs << 'lib'
|
32
|
+
t.libs << 'test'
|
33
|
+
t.pattern = 'test/**/*_test.rb'
|
34
|
+
t.verbose = false
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
task :default => :test
|
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module FacebookRailsController
|
4
|
+
def facebook_href(path = '/')
|
5
|
+
FACEBOOK['f8app_home'].to_s + path
|
6
|
+
end
|
7
|
+
|
8
|
+
def direct_href(path = '/')
|
9
|
+
FACEBOOK['f8app_callback'].to_s + path
|
10
|
+
end
|
11
|
+
|
12
|
+
def facebook_api
|
13
|
+
@facebook_api ||= Koala::Facebook::API.new(session[:access_token])
|
14
|
+
end
|
15
|
+
|
16
|
+
def current_user_data
|
17
|
+
@current_user_data ||= facebook_api.get_object("me")
|
18
|
+
return @current_user_data || {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def current_user_f8id
|
22
|
+
session[:user_f8id] ||= current_user_data["id"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def current_user_friends_f8ids
|
26
|
+
@current_user_friends_f8ids ||= facebook_api.get_connections('me','friends', :fields => 'id').collect { |f| f['id']}
|
27
|
+
rescue Exception => e
|
28
|
+
logger.error 'FACEBOOK ERROR: ' + e.to_s
|
29
|
+
return []
|
30
|
+
end
|
31
|
+
|
32
|
+
def check_if_f8ids_are_friends(first_f8id, second_f8id)
|
33
|
+
#handle corner cases with anonymous users
|
34
|
+
return false if first_f8id.nil? or second_f8id.nil?
|
35
|
+
|
36
|
+
return (facebook_api.fql_query('SELECT uid2 FROM friend where uid1=' + first_f8id + ' AND uid2=' + second_f8id).size > 0)
|
37
|
+
rescue Exception => e
|
38
|
+
logger.error "ERROR:" + e.to_s
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
|
42
|
+
def url_smart_add_params(url, params = {})
|
43
|
+
new_url = url + (url.index(/\w\?\w/) ? '&' : '?')
|
44
|
+
params.each_pair {|key, value| new_url << key.to_s << "=" << value.to_s << '&'}
|
45
|
+
return new_url.chop
|
46
|
+
end
|
47
|
+
|
48
|
+
def clean_and_recode_current_url(escape = true)
|
49
|
+
omit_keys = ["_method", "format", "signed_request", "code", "clear_users_session"]
|
50
|
+
options = (params||{}).clone
|
51
|
+
options = options.reject{|k,v| omit_keys.include?(k.to_s)}
|
52
|
+
options = options.merge({:only_path => false})
|
53
|
+
if escape
|
54
|
+
return CGI.escape(url_for(options))
|
55
|
+
else
|
56
|
+
return url_for(options)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def top_redirect_to(url)
|
61
|
+
@redirect_url = CGI.unescape(url)
|
62
|
+
render :layout => false, :inline => <<-HTML
|
63
|
+
<html><head>
|
64
|
+
<script type="text/javascript">
|
65
|
+
window.top.location.href = "<%=raw @redirect_url -%>";
|
66
|
+
</script>
|
67
|
+
<noscript>
|
68
|
+
<meta http-equiv="refresh" content="0;url=<%= @redirect_url %>" />
|
69
|
+
<meta http-equiv="window-target" content="_top" />
|
70
|
+
</noscript>
|
71
|
+
</head></html>
|
72
|
+
HTML
|
73
|
+
end
|
74
|
+
|
75
|
+
def authenticated_by_facebook?
|
76
|
+
return !session[:access_token].nil?
|
77
|
+
end
|
78
|
+
|
79
|
+
#Will only try to collect facebook credentials but it will let the user in even there aren't any
|
80
|
+
def try_facebook_authentication
|
81
|
+
attempt_to_acquire_facebook_credentials do |fb_oauth|
|
82
|
+
clear_oauth
|
83
|
+
end
|
84
|
+
rescue Exception => e
|
85
|
+
clear_oauth
|
86
|
+
logger.error "FACEBOOK AUTH EXCEPTION: #{ e.inspect } #{ e.backtrace }"
|
87
|
+
end
|
88
|
+
|
89
|
+
#Will force user to authorize the application to access the current url
|
90
|
+
def ensure_authenticated_to_facebook
|
91
|
+
attempt_to_acquire_facebook_credentials do |fb_oauth|
|
92
|
+
if params[:error_reason] == "user_denied"
|
93
|
+
redirect_url = root_url
|
94
|
+
else
|
95
|
+
redirect_url = fb_oauth.url_for_oauth_code(:callback => clean_and_recode_current_url, :permissions => Game.extended_permissions)
|
96
|
+
end
|
97
|
+
top_redirect_to(redirect_url)
|
98
|
+
end
|
99
|
+
rescue Exception => e
|
100
|
+
logger.error 'AUTHENTICATION ERROR: ' + e.to_s
|
101
|
+
top_redirect_to clean_and_recode_current_url(false)
|
102
|
+
end
|
103
|
+
|
104
|
+
#prepend before filter to force authentication when collect_facebook_authentication is called
|
105
|
+
def require_facebook_authentication
|
106
|
+
@require_fb_authentication = true
|
107
|
+
end
|
108
|
+
|
109
|
+
#Add method to before filter to collect user
|
110
|
+
def collect_facebook_authentication
|
111
|
+
if @require_fb_authentication
|
112
|
+
ensure_authenticated_to_facebook
|
113
|
+
else
|
114
|
+
try_facebook_authentication
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_facebook_locale
|
119
|
+
puts current_user_data.inspect
|
120
|
+
current_user_data["locale"]
|
121
|
+
rescue Exception => e
|
122
|
+
logger.warn "Facebook locale error: #{ e.inspect }"
|
123
|
+
session[:f8_locale] || "en_US"
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
#Tries to extract facebook credentials, if it thinks a redirect is needed it yields to the block
|
128
|
+
#and returns false else it returns true
|
129
|
+
#Will let exceptions propagate
|
130
|
+
def attempt_to_acquire_facebook_credentials
|
131
|
+
if params[:clear_users_session]
|
132
|
+
clear_oauth
|
133
|
+
logger.warn "User's session cleared"
|
134
|
+
end
|
135
|
+
|
136
|
+
#First check we received the call with a signed_request parameter, as that means a fresh token
|
137
|
+
if params[:signed_request]
|
138
|
+
fb_oauth = Koala::Facebook::OAuth.new
|
139
|
+
f8_params = fb_oauth.parse_signed_request(params.delete(:signed_request))
|
140
|
+
session[:f8_locale] = (f8_params and f8_params["user"]) ? f8_params["user"]["locale"] : nil
|
141
|
+
#puts "request params: #{ f8_params.inspect }"
|
142
|
+
if f8_params["oauth_token"]
|
143
|
+
set_oauth f8_params["oauth_token"], f8_params["expires"].to_i, f8_params["user_id"]
|
144
|
+
else
|
145
|
+
yield(fb_oauth)
|
146
|
+
return false
|
147
|
+
end
|
148
|
+
|
149
|
+
#Then check if received a code because we just came from authorization, that also means a fresh token
|
150
|
+
elsif params[:code]
|
151
|
+
fb_oauth = Koala::Facebook::OAuth.new(clean_and_recode_current_url(false))
|
152
|
+
oauth_token_info = fb_oauth.get_access_token_info(params.delete(:code))
|
153
|
+
#puts "code params: #{ oauth_token_info.inspect }"
|
154
|
+
set_oauth oauth_token_info['access_token'], Time.now.to_i + oauth_token_info['expires'].to_i, nil
|
155
|
+
|
156
|
+
else
|
157
|
+
#Try to parse cookies
|
158
|
+
fb_oauth = Koala::Facebook::OAuth.new
|
159
|
+
f8_params = fb_oauth.get_user_info_from_cookies(cookies)
|
160
|
+
#puts "cookie params: #{ f8_params.inspect }"
|
161
|
+
if f8_params and f8_params["access_token"]
|
162
|
+
set_oauth f8_params["access_token"], Time.now.to_i + f8_params["expires"].to_i, f8_params["user_id"]
|
163
|
+
|
164
|
+
#Then we check if have a valid token stored in the session
|
165
|
+
#puts "session: #{ session.inspect }"
|
166
|
+
elsif session[:access_token] and session[:expires] > Time.now.to_i
|
167
|
+
#Do nothing
|
168
|
+
|
169
|
+
#if all else fails (we lost the session or something went wrong in the request sending) redirect the authorization
|
170
|
+
#screen. If the user has already authorized the application he will pass straight through without noticing and we
|
171
|
+
#will receive a fresh token via the code parameter
|
172
|
+
else
|
173
|
+
yield(fb_oauth)
|
174
|
+
return false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
return true
|
179
|
+
end
|
180
|
+
|
181
|
+
def set_oauth(access_token = nil, expires = nil, user_f8id = nil)
|
182
|
+
session[:access_token] = access_token
|
183
|
+
session[:expires] = expires
|
184
|
+
session[:user_f8id] = user_f8id
|
185
|
+
@facebook_api = nil
|
186
|
+
end
|
187
|
+
|
188
|
+
def clear_oauth
|
189
|
+
set_oauth nil, nil, nil
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module FacebookRailsHelper
|
2
|
+
def reload_back_to_facebook_if_needed_js
|
3
|
+
return '<script>' +
|
4
|
+
'if (top == self)' +
|
5
|
+
'{' +
|
6
|
+
"top.location = '#{facebook_href(url_for( { :controller => controller.controller_name, :action => controller.action_name}.merge params.reject {|k,v| k == 'signed_request'}))}';" +
|
7
|
+
'}' +
|
8
|
+
'</script>'
|
9
|
+
end
|
10
|
+
|
11
|
+
def facebook_initialization one_time_resize = false, app_id = FACEBOOK['app_id'], user_f8id = current_user_f8id
|
12
|
+
resize = %{
|
13
|
+
var domLoaded = false;
|
14
|
+
var facebookLoaded = false;
|
15
|
+
var pageLoaded = false;
|
16
|
+
|
17
|
+
function pageLoad() {
|
18
|
+
if (domLoaded && facebookLoaded) {
|
19
|
+
if (!pageLoaded) {
|
20
|
+
pageLoaded = true;
|
21
|
+
$(document).trigger('page_loaded');
|
22
|
+
}
|
23
|
+
sizeToMain();
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
function sizeToMain() {
|
28
|
+
if (domLoaded && facebookLoaded) {
|
29
|
+
var height = $('#main').outerHeight();
|
30
|
+
if(height > 100) {
|
31
|
+
FB.Canvas.setSize({ width: 760, height: height + 200 });
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
$(document).ready(function () {
|
37
|
+
domLoaded = true;
|
38
|
+
pageLoad();
|
39
|
+
});
|
40
|
+
$(window).load(function() {
|
41
|
+
domLoaded = true; //not neccessary
|
42
|
+
pageLoad();
|
43
|
+
});
|
44
|
+
}
|
45
|
+
|
46
|
+
login_status = if user_f8id
|
47
|
+
%{
|
48
|
+
FB.getLoginStatus(function(response) {
|
49
|
+
if ((response.authResponse && response.authResponse.userID == '#{ user_f8id }') ||
|
50
|
+
(response.session && response.session.uid == '#{ user_f8id }')) {
|
51
|
+
// logged in and connected user - continue
|
52
|
+
$(document).trigger('got_facebook_status');
|
53
|
+
} else {
|
54
|
+
// no user session available or new user - clear old user's session
|
55
|
+
window.location.href = window.location.href + (window.location.href.indexOf('?') >= 0 ? '&' : '?') + 'clear_users_session=true';
|
56
|
+
}
|
57
|
+
}, true); //force session status reloading
|
58
|
+
}
|
59
|
+
else
|
60
|
+
%{
|
61
|
+
FB.getLoginStatus(function(response) {
|
62
|
+
$(document).trigger('got_facebook_status');
|
63
|
+
});
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
%{
|
68
|
+
<div id="fb-root"></div>
|
69
|
+
<script>
|
70
|
+
#{ resize if one_time_resize }
|
71
|
+
window.fbAsyncInit = function() {
|
72
|
+
FB.init({ appId: '#{ app_id }',
|
73
|
+
status: true,
|
74
|
+
cookie: true,
|
75
|
+
xfbml: true });
|
76
|
+
$(document).trigger('facebook_init');
|
77
|
+
#{ one_time_resize ? 'facebookLoaded = true; pageLoad();' : 'FB.Canvas.setAutoGrow();' }
|
78
|
+
#{ login_status }
|
79
|
+
};
|
80
|
+
|
81
|
+
(function() {
|
82
|
+
var e = document.createElement('script'); e.async = true;
|
83
|
+
e.src = document.location.protocol +
|
84
|
+
'//connect.facebook.net/#{ get_facebook_locale }/all.js';
|
85
|
+
document.getElementById('fb-root').appendChild(e);
|
86
|
+
}());
|
87
|
+
</script>
|
88
|
+
}.html_safe
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'koala'
|
2
|
+
|
3
|
+
module FacebookRails
|
4
|
+
|
5
|
+
class Engine < Rails::Engine
|
6
|
+
|
7
|
+
initializer "facebook_rails.load_app_instance_data" do |app|
|
8
|
+
FacebookRails.setup do |config|
|
9
|
+
config.app_root = app.root
|
10
|
+
config.app_env = Rails.env
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer "facebook_rails.facebook" do
|
15
|
+
::FACEBOOK = YAML.load_file(FacebookRails.app_root.join("config/facebook.yml"))[Rails.env]
|
16
|
+
FACEBOOK.default = ''
|
17
|
+
|
18
|
+
::Koala.http_service.http_options[:timeout] = FACEBOOK[:timeout].to_i unless FACEBOOK[:timeout].blank?
|
19
|
+
|
20
|
+
::Koala::Facebook::OAuth.class_eval do
|
21
|
+
def initialize_with_default_settings(*args)
|
22
|
+
case args.size
|
23
|
+
when 0, 1
|
24
|
+
raise "application id and/or secret are not specified in the config" unless FACEBOOK['app_id'] && FACEBOOK['secret_key']
|
25
|
+
initialize_without_default_settings(FACEBOOK['app_id'].to_s, FACEBOOK['secret_key'].to_s, args.first)
|
26
|
+
when 2, 3
|
27
|
+
initialize_without_default_settings(*args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method_chain :initialize, :default_settings
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
initializer "facebook_rails.application_controller" do
|
36
|
+
ActionController::Base.send :include, FacebookRailsController
|
37
|
+
|
38
|
+
ActionController::Base.send :helper_method, :facebook_href
|
39
|
+
ActionController::Base.send :helper_method, :direct_href
|
40
|
+
ActionController::Base.send :helper_method, :current_user_f8id
|
41
|
+
ActionController::Base.send :helper_method, :get_facebook_locale
|
42
|
+
end
|
43
|
+
|
44
|
+
initializer "facebook_rails.application_helper" do
|
45
|
+
ActionView::Base.send :include, FacebookRailsHelper
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "active_support/dependencies"
|
2
|
+
|
3
|
+
module FacebookRails
|
4
|
+
|
5
|
+
# Our host application root path
|
6
|
+
# We set this when the engine is initialized
|
7
|
+
mattr_accessor :app_root
|
8
|
+
mattr_accessor :app_env
|
9
|
+
|
10
|
+
# Yield self on setup for nice config blocks
|
11
|
+
def self.setup
|
12
|
+
yield self
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'facebook_rails/engine'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class FacebookRailsGenerator < Rails::Generators::Base
|
4
|
+
def self.source_root
|
5
|
+
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
|
6
|
+
end
|
7
|
+
|
8
|
+
def copy_configuration
|
9
|
+
template 'facebook.yml', 'config/facebook.yml'
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#TODO Go to https://developers.facebook.com/apps, create a new App and enter the correct values here
|
2
|
+
|
3
|
+
# config/facebook.yml
|
4
|
+
development:
|
5
|
+
app_id: YOUR_APP_ID
|
6
|
+
secret_key: YOUR_SECRET
|
7
|
+
#Slijede drap dodaci
|
8
|
+
f8app_home: http://apps.facebook.com/CANVAS_NAME #bez zadnjeg '/'
|
9
|
+
f8app_callback: CALLBACK_URL #bez zadnjeg '/'
|
10
|
+
#server_subdir:
|
11
|
+
timeout: 3
|
12
|
+
|
13
|
+
test:
|
14
|
+
app_id: YOUR_APP_ID
|
15
|
+
secret_key: YOUR_SECRET
|
16
|
+
#Slijede drap dodaci
|
17
|
+
f8app_home: CANVAS_URL #bez zadnjeg '/'
|
18
|
+
f8app_callback: CALLBACK_URL #bez zadnjeg '/'
|
19
|
+
#server_subdir:
|
20
|
+
timeout: 3
|
21
|
+
|
22
|
+
production:
|
23
|
+
app_id: YOUR_APP_ID
|
24
|
+
secret_key: YOUR_SECRET
|
25
|
+
#Slijede drap dodaci
|
26
|
+
f8app_home: CANVAS_URL #bez zadnjeg '/'
|
27
|
+
f8app_callback: CALLBACK_URL #bez zadnjeg '/'
|
28
|
+
#server_subdir:
|
29
|
+
timeout: 3
|