livefyre 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +147 -0
- data/Rakefile +10 -0
- data/app/assets/javascripts/livefyre.js.coffee +72 -0
- data/app/assets/javascripts/livefyre.js.js +117 -0
- data/lib/livefyre/client.rb +117 -0
- data/lib/livefyre/controller_extensions.rb +58 -0
- data/lib/livefyre/domain.rb +186 -0
- data/lib/livefyre/engine.rb +6 -0
- data/lib/livefyre/helpers.rb +56 -0
- data/lib/livefyre/model_extensions.rb +76 -0
- data/lib/livefyre/site.rb +138 -0
- data/lib/livefyre/user.rb +110 -0
- data/lib/livefyre/version.rb +3 -0
- data/lib/livefyre.rb +50 -0
- data/livefyre.gemspec +26 -0
- data/railties/railtie.rb +9 -0
- data/spec/livefyre/client_spec.rb +104 -0
- data/spec/livefyre/domain_spec.rb +294 -0
- data/spec/livefyre/livefyre_spec.rb +30 -0
- data/spec/livefyre/model_spec.rb +92 -0
- data/spec/livefyre/site_spec.rb +211 -0
- data/spec/livefyre/user_spec.rb +122 -0
- data/spec/spec_helper.rb +26 -0
- metadata +196 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Mashable, Inc
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# Livefyre
|
2
|
+
|
3
|
+
Interface library for Livefyre's API. Currently a mishmash of the v2 and v3 APIs.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'livefyre'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install livefyre
|
18
|
+
|
19
|
+
## Documentation
|
20
|
+
|
21
|
+
Full documentation is available [on GitHub](http://mashable.github.com/livefyre/frames.html).
|
22
|
+
|
23
|
+
You can generate full documentation yourself from the source tree. Requires the yard-tomdoc plugin.
|
24
|
+
|
25
|
+
yard --plugin yard-tomdoc -o doc
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
You can set a default configuration object for Livefyre, which will prevent you from having to pass a client to
|
30
|
+
all your object proxies manually.
|
31
|
+
|
32
|
+
Livefyre.config = {
|
33
|
+
:network => "foo.fyre.co",
|
34
|
+
:network_key => "blorgons",
|
35
|
+
:site_id => 1234,
|
36
|
+
:site_key => "minerva",
|
37
|
+
:system_token => "your_long_lived_system_token",
|
38
|
+
:domain => "zor.t123.livefyre.com"
|
39
|
+
}
|
40
|
+
|
41
|
+
If you're using this gem from Rails, we recommend doing this from an initializer.
|
42
|
+
|
43
|
+
Once that's set, you're ready to start talking to Livefyre.
|
44
|
+
|
45
|
+
domain = Livefyre::Domain.new
|
46
|
+
domain.set_pull_url "http://foo.bar/users/{id}/pull/"
|
47
|
+
|
48
|
+
user = Livefyre::User.new("some_user_id")
|
49
|
+
user.refresh # Invoke ping-to-pull
|
50
|
+
|
51
|
+
## Using with Rails
|
52
|
+
|
53
|
+
Integration with Rails is straightforward, but does require some setup.
|
54
|
+
|
55
|
+
### Controller integration
|
56
|
+
|
57
|
+
You need to add a route to your routes file to handle profile pull requests from Livefyre. That'll look something like:
|
58
|
+
|
59
|
+
get "/livefyre/:id/pull", :to => "users#pull"
|
60
|
+
|
61
|
+
Of course, you need a matching controller action
|
62
|
+
|
63
|
+
def pull
|
64
|
+
# Checks the validity of the JWT that Livefyre sends with pull requests. Throws an exception if it's no good.
|
65
|
+
validate_livefyre_request!
|
66
|
+
|
67
|
+
user = User.find(params[:id])
|
68
|
+
|
69
|
+
# livefile_profile will attempt to generate valid Livefire profile dump from the passed user record by guessing at field names.
|
70
|
+
# You can pass overides in a hash as the second option, or you can always generate your own data structure.
|
71
|
+
render :json => livefire_profile(user, :image => user.profile_image_url).to_json
|
72
|
+
end
|
73
|
+
|
74
|
+
Finally, you'll need to set up a pull URL. Since this is done via the API, you are expected to do it manually. From a Rails console is fine, though
|
75
|
+
you may do it any other way you please, too. Livefyre will substitute the string "{id}" for the user ID it wants data for.
|
76
|
+
|
77
|
+
Livefyre::Domain.new.set_pull_url "http://your.domain.com/livefyre/{id}/pull"
|
78
|
+
|
79
|
+
You may want to invoke user updates when you save the user record.
|
80
|
+
|
81
|
+
def update
|
82
|
+
# ... user record updates here!
|
83
|
+
Livefyre::User.new( user._id ).refresh
|
84
|
+
end
|
85
|
+
|
86
|
+
Or you can have the gem do it automatically from the model:
|
87
|
+
|
88
|
+
class User < ActiveRecord::Base
|
89
|
+
# ...
|
90
|
+
|
91
|
+
livefyre_user :update_on => [:email, :display_name]
|
92
|
+
end
|
93
|
+
|
94
|
+
You can even have the gem do your ping updated asynchronously with Resque
|
95
|
+
|
96
|
+
class User < ActiveRecord::Base
|
97
|
+
# ...
|
98
|
+
|
99
|
+
livefyre_user :update_on => [:email, :display_name], :defer => true
|
100
|
+
end
|
101
|
+
|
102
|
+
This will enqueue a ping-to-pull job in the "livefyre" queue. Make sure you have a worker running that'll handle that queue!
|
103
|
+
|
104
|
+
### View integration
|
105
|
+
|
106
|
+
|
107
|
+
In the location that you want to use your comment form, include something like the following:
|
108
|
+
|
109
|
+
<%= livefyre_comments post.id, post.title, post_url(post), post.tags %>
|
110
|
+
|
111
|
+
You'll also need to boot Livefyre with Javascript. In your application.js, you'll want to include the Livefyre loader in your manifest:
|
112
|
+
|
113
|
+
//=require livefyre.js
|
114
|
+
|
115
|
+
And then somewhere in your application.js, you'll want to actually boot:
|
116
|
+
|
117
|
+
window.initLivefyre({
|
118
|
+
login: function() {
|
119
|
+
// Things to do when the user clicks the "sign in" link. You probably want to
|
120
|
+
// take your user through a login cycle in a popup window, which includes calling
|
121
|
+
// the livefyre_login(user_id, user_name) method.
|
122
|
+
window.location = "/login";
|
123
|
+
},
|
124
|
+
logout: function() {
|
125
|
+
// things to do when the user clicks the "sign out" link. You probably want to take
|
126
|
+
// your user through the logout cycle, including a call to livefyre_logout.
|
127
|
+
window.location = "/logout";
|
128
|
+
},
|
129
|
+
viewProfile: function(handlers, author) {
|
130
|
+
// Handler for when a user's name is clicked in a comment
|
131
|
+
window.location = "/" + author;
|
132
|
+
},
|
133
|
+
editProfile: function(handlers, author) {
|
134
|
+
// Handler for when a user wants to edit their profile from the Livefyre user dropdown.
|
135
|
+
window.location = "/" + author + "/edit";
|
136
|
+
}
|
137
|
+
});
|
138
|
+
|
139
|
+
That's it!
|
140
|
+
|
141
|
+
## Contributing
|
142
|
+
|
143
|
+
1. Fork it
|
144
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
145
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
146
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
147
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
defaultDelegate = (options) ->
|
2
|
+
authDelegate = new fyre.conv.RemoteAuthDelegate()
|
3
|
+
authDelegate.login = (handlers) ->
|
4
|
+
if options.login
|
5
|
+
options.login(handlers)
|
6
|
+
|
7
|
+
authDelegate.logout = (handlers) ->
|
8
|
+
if options.logout
|
9
|
+
options.logout(handlers)
|
10
|
+
authDelegate.viewProfile = (handlers, author) ->
|
11
|
+
if options.viewProfile
|
12
|
+
if options.viewProfile(handlers, author)
|
13
|
+
handlers.success()
|
14
|
+
|
15
|
+
authDelegate.editProfile = (handlers, author) ->
|
16
|
+
if options.editProfile
|
17
|
+
if options.editProfile(handlers, author)
|
18
|
+
handlers.success()
|
19
|
+
|
20
|
+
loadScriptAsync = null
|
21
|
+
(->
|
22
|
+
__loadedScripts = []
|
23
|
+
fjs = null
|
24
|
+
loadScriptAsync = (source, id, content, options) ->
|
25
|
+
content = null if !content
|
26
|
+
return if (document.getElementById(id))
|
27
|
+
return if __loadedScripts[id]
|
28
|
+
__loadedScripts[id] = true
|
29
|
+
fjs = document.getElementsByTagName('script')[0] unless fjs
|
30
|
+
js = document.createElement("script")
|
31
|
+
js.id = id
|
32
|
+
js.async = true
|
33
|
+
js.src = source
|
34
|
+
js.innerHTML = content
|
35
|
+
js[k] = v for k, v of options if options
|
36
|
+
|
37
|
+
fjs.parentNode.insertBefore(js, fjs)
|
38
|
+
js
|
39
|
+
)()
|
40
|
+
|
41
|
+
livefyreInitialized = false
|
42
|
+
@initLivefyre = (options) ->
|
43
|
+
if livefyreInitialized
|
44
|
+
throw "Livefyre has already been initialized"
|
45
|
+
livefyreInitialized = true
|
46
|
+
e = document.getElementById(options.element_id || "livefyre_comments")
|
47
|
+
if e
|
48
|
+
options.config ||=
|
49
|
+
checksum: e.getAttribute("data-checksum")
|
50
|
+
collectionMeta: e.getAttribute("data-collection-meta")
|
51
|
+
articleId: e.getAttribute("data-article-id")
|
52
|
+
siteId: e.getAttribute("data-site-id")
|
53
|
+
el: e.id
|
54
|
+
|
55
|
+
options.network ||= e.getAttribute("data-network")
|
56
|
+
options.domain ||= e.getAttribute("data-domain")
|
57
|
+
options.root ||= e.getAttribute("data-root")
|
58
|
+
|
59
|
+
@FYRE_LOADED_CB = ->
|
60
|
+
opts =
|
61
|
+
network: options.network
|
62
|
+
authDelegate: options.delegate || defaultDelegate(options)
|
63
|
+
|
64
|
+
fyre.conv.load opts, [options.config], ->
|
65
|
+
token = $.cookie(options.cookie_name || "livefyre_utoken")
|
66
|
+
if token
|
67
|
+
try
|
68
|
+
fyre.conv.login(token)
|
69
|
+
catch error
|
70
|
+
window.console.log "Error logging in:", e if window.console
|
71
|
+
|
72
|
+
element = loadScriptAsync "http://#{options.root}/wjs/v3.0/javascripts/livefyre.js", null, null, {"data-lf-domain": options.network}
|
@@ -0,0 +1,117 @@
|
|
1
|
+
// Generated by CoffeeScript 1.3.3
|
2
|
+
(function() {
|
3
|
+
var defaultDelegate, livefyreInitialized, loadScriptAsync;
|
4
|
+
|
5
|
+
defaultDelegate = function(options) {
|
6
|
+
var authDelegate;
|
7
|
+
authDelegate = new fyre.conv.RemoteAuthDelegate();
|
8
|
+
authDelegate.login = function(handlers) {
|
9
|
+
if (options.login) {
|
10
|
+
return options.login(handlers);
|
11
|
+
}
|
12
|
+
};
|
13
|
+
authDelegate.logout = function(handlers) {
|
14
|
+
if (options.logout) {
|
15
|
+
return options.logout(handlers);
|
16
|
+
}
|
17
|
+
};
|
18
|
+
authDelegate.viewProfile = function(handlers, author) {
|
19
|
+
if (options.viewProfile) {
|
20
|
+
if (options.viewProfile(handlers, author)) {
|
21
|
+
return handlers.success();
|
22
|
+
}
|
23
|
+
}
|
24
|
+
};
|
25
|
+
return authDelegate.editProfile = function(handlers, author) {
|
26
|
+
if (options.editProfile) {
|
27
|
+
if (options.editProfile(handlers, author)) {
|
28
|
+
return handlers.success();
|
29
|
+
}
|
30
|
+
}
|
31
|
+
};
|
32
|
+
};
|
33
|
+
|
34
|
+
loadScriptAsync = null;
|
35
|
+
|
36
|
+
(function() {
|
37
|
+
var fjs, __loadedScripts;
|
38
|
+
__loadedScripts = [];
|
39
|
+
fjs = null;
|
40
|
+
return loadScriptAsync = function(source, id, content, options) {
|
41
|
+
var js, k, v;
|
42
|
+
if (!content) {
|
43
|
+
content = null;
|
44
|
+
}
|
45
|
+
if (document.getElementById(id)) {
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
if (__loadedScripts[id]) {
|
49
|
+
return;
|
50
|
+
}
|
51
|
+
__loadedScripts[id] = true;
|
52
|
+
if (!fjs) {
|
53
|
+
fjs = document.getElementsByTagName('script')[0];
|
54
|
+
}
|
55
|
+
js = document.createElement("script");
|
56
|
+
js.id = id;
|
57
|
+
js.async = true;
|
58
|
+
js.src = source;
|
59
|
+
js.innerHTML = content;
|
60
|
+
if (options) {
|
61
|
+
for (k in options) {
|
62
|
+
v = options[k];
|
63
|
+
js[k] = v;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
fjs.parentNode.insertBefore(js, fjs);
|
67
|
+
return js;
|
68
|
+
};
|
69
|
+
})();
|
70
|
+
|
71
|
+
livefyreInitialized = false;
|
72
|
+
|
73
|
+
this.initLivefyre = function(options) {
|
74
|
+
var e, element;
|
75
|
+
if (livefyreInitialized) {
|
76
|
+
throw "Livefyre has already been initialized";
|
77
|
+
}
|
78
|
+
livefyreInitialized = true;
|
79
|
+
e = document.getElementById(options.element_id || "livefyre_comments");
|
80
|
+
if (e) {
|
81
|
+
options.config || (options.config = {
|
82
|
+
checksum: e.getAttribute("data-checksum"),
|
83
|
+
collectionMeta: e.getAttribute("data-collection-meta"),
|
84
|
+
articleId: e.getAttribute("data-article-id"),
|
85
|
+
siteId: e.getAttribute("data-site-id"),
|
86
|
+
el: e.id
|
87
|
+
});
|
88
|
+
options.network || (options.network = e.getAttribute("data-network"));
|
89
|
+
options.domain || (options.domain = e.getAttribute("data-domain"));
|
90
|
+
options.root || (options.root = e.getAttribute("data-root"));
|
91
|
+
this.FYRE_LOADED_CB = function() {
|
92
|
+
var opts;
|
93
|
+
opts = {
|
94
|
+
network: options.network,
|
95
|
+
authDelegate: options.delegate || defaultDelegate(options)
|
96
|
+
};
|
97
|
+
return fyre.conv.load(opts, [options.config], function() {
|
98
|
+
var token;
|
99
|
+
token = $.cookie(options.cookie_name || "livefyre_utoken");
|
100
|
+
if (token) {
|
101
|
+
try {
|
102
|
+
return fyre.conv.login(token);
|
103
|
+
} catch (error) {
|
104
|
+
if (window.console) {
|
105
|
+
return window.console.log("Error logging in:", e);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
});
|
110
|
+
};
|
111
|
+
return element = loadScriptAsync("http://" + options.root + "/wjs/v3.0/javascripts/livefyre.js", null, null, {
|
112
|
+
"data-lf-domain": options.network
|
113
|
+
});
|
114
|
+
}
|
115
|
+
};
|
116
|
+
|
117
|
+
}).call(this);
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Livefyre
|
2
|
+
# Public: Primary interface to the Livefyre API
|
3
|
+
class Client
|
4
|
+
extend Forwardable
|
5
|
+
# Public: Valid roles for #set_user_role
|
6
|
+
ROLES = %w(admin member none outcast owner)
|
7
|
+
|
8
|
+
# Public: Valid scopes for #set_user_role
|
9
|
+
SCOPES = %w(domain site conv)
|
10
|
+
|
11
|
+
attr_accessor :host, :key, :options, :system_token, :http_client
|
12
|
+
|
13
|
+
def_delegators :http_client, :get, :post, :delete, :put
|
14
|
+
|
15
|
+
# Public: Create a new Livefyre client.
|
16
|
+
#
|
17
|
+
# options - [Hash] array of options to pass to the client for initialization
|
18
|
+
# :host - your Livefyre network_host
|
19
|
+
# :key - your Livefyre network_key
|
20
|
+
# :system_token - your Livefyre long-lived system user key
|
21
|
+
def initialize(options = {})
|
22
|
+
@options = options.clone
|
23
|
+
@host = options.delete(:network) || options.delete(:host)
|
24
|
+
raise "Invalid host" if @host.nil?
|
25
|
+
@http_client = Faraday.new(:url => "http://#{@host}")
|
26
|
+
|
27
|
+
@key = options.delete(:secret) || options.delete(:key) || options.delete(:network_key)
|
28
|
+
raise "Invalid secret key" if @key.nil?
|
29
|
+
|
30
|
+
@system_token = options.delete(:system_token)
|
31
|
+
raise "Invalid system token" if @system_token.nil?
|
32
|
+
end
|
33
|
+
|
34
|
+
# Public: Sign a data structure with this client's network key.
|
35
|
+
#
|
36
|
+
# Returns [String] A signed JWT token
|
37
|
+
def sign(data)
|
38
|
+
JWT.encode(data, @key)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Public: Validates and decodes a JWT token
|
42
|
+
#
|
43
|
+
# Returns [Hash] A hash of data passed from the token
|
44
|
+
# Raises [JWT::DecodeError] if invalid token contents or signature
|
45
|
+
def validate(data)
|
46
|
+
JWT.decode(data, @key)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Public: Create a {Livefyre::User} with this client's credentials.
|
50
|
+
#
|
51
|
+
# uid - the user ID to create a Livefyre user for. This should be the ID used to reference this user in Livefyre's system.
|
52
|
+
# display_name - the displayed name for this user. Optional.
|
53
|
+
#
|
54
|
+
# Returns [Livefyre::User]
|
55
|
+
def user(uid, display_name = nil)
|
56
|
+
User.new(uid, self, display_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Public: Sets a user's role (affiliation) in a given scope.
|
60
|
+
#
|
61
|
+
# user_id - The user ID (without the host) to set roles for
|
62
|
+
# role - The {ROLES role} to set.
|
63
|
+
# scope - The {SCOPES scope} for which to set this role.
|
64
|
+
# scope_id - In the case that the given scope requires identification, specifies which scope to operate on.
|
65
|
+
#
|
66
|
+
# Examples
|
67
|
+
#
|
68
|
+
# set_user_role(1234, "owner", "domain")
|
69
|
+
# set_user_role(1234, "moderator", "site", site_id)
|
70
|
+
# set_user_role(1234, "moderator", "conv", conversation_id)
|
71
|
+
#
|
72
|
+
#
|
73
|
+
# Returns [Bool] true on success
|
74
|
+
# Raises APIException if the request failed
|
75
|
+
def set_user_role(user_id, role, scope = 'domain', scope_id = nil)
|
76
|
+
raise "Invalid scope" unless SCOPES.include? scope
|
77
|
+
raise "Invalid role" unless ROLES.include? role
|
78
|
+
|
79
|
+
post_data = {
|
80
|
+
:affiliation => role,
|
81
|
+
:lftoken => system_token,
|
82
|
+
}
|
83
|
+
case scope
|
84
|
+
when "domain"
|
85
|
+
post_data[:domain_wide] = 1
|
86
|
+
when "conv"
|
87
|
+
raise "Invalid scope_id" if scope_id.nil?
|
88
|
+
post_data[:conv_id] = scope_id
|
89
|
+
when "site"
|
90
|
+
raise "Invalid scope_id" if scope_id.nil?
|
91
|
+
post_data[:site_id] = scope_id
|
92
|
+
end
|
93
|
+
result = post "/api/v1.1/private/management/user/#{jid(user_id)}/role/", post_data
|
94
|
+
if result.success?
|
95
|
+
true
|
96
|
+
else
|
97
|
+
raise APIException.new(result.body)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Public: Transform the given ID into a jid
|
102
|
+
#
|
103
|
+
# id - a string value to compose the JID with
|
104
|
+
#
|
105
|
+
# Returns [String] JID
|
106
|
+
def jid(id)
|
107
|
+
"%s@%s" % [id, host]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Internal: Returns a cleaner string representation of this object
|
111
|
+
#
|
112
|
+
# Returns [String] representation of this class
|
113
|
+
def to_s
|
114
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16).rjust(14, "0")} host='#{host}' key='#{key}'>"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Livefyre
|
2
|
+
# Public: Controller extensions for Rails. Adds methods to be called from your controller to integrate with Livefyre.
|
3
|
+
module Controller
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# Public: Creates the Livefyre session cookies. Should be called when the user logs in.
|
7
|
+
def livefyre_login(id, display_name)
|
8
|
+
cookie = (Livefyre.config[:cookie_options] || {}).clone || {:path => "/", :expires => Time.now + 1.year}
|
9
|
+
expiry = cookie.delete(:expires) || (Time.now + 1.year)
|
10
|
+
|
11
|
+
token = {
|
12
|
+
:domain => Livefyre.client.host,
|
13
|
+
:user_id => id,
|
14
|
+
:expires => expiry.to_i,
|
15
|
+
:display_name => display_name
|
16
|
+
}
|
17
|
+
|
18
|
+
name = cookie.delete(:name) || "livefyre_utoken"
|
19
|
+
cookies[name] = cookie.merge(:value => JWT.encode(token, Livefyre.client.key), :expires => expiry)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Public: Destroys the Livefyre session cookies. Should be called when the user logs out
|
23
|
+
def livefyre_logout
|
24
|
+
name = (Livefyre.config[:cookie_options] || {})[:name] || "livefyre_utoken"
|
25
|
+
cookies.delete(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Public: Attempt to generate valid Livefire profile dump from the passed user record by guessing at field names.
|
29
|
+
#
|
30
|
+
# user - The user record to generate data from. Assumes it's ActiveModel-ish.
|
31
|
+
# values - [Hash] of values to force values for, rather than guessing at.
|
32
|
+
#
|
33
|
+
# Returns [Hash] suitable for conversion to JSON
|
34
|
+
def livefire_profile(user, values = {})
|
35
|
+
{
|
36
|
+
:id => user.id,
|
37
|
+
:display_name => user.try(:display_name) || user.try(:name) || user.try(:username),
|
38
|
+
:email => user.try(:email),
|
39
|
+
:profile => url_for(user),
|
40
|
+
:settings_url => url_for(:edit, user),
|
41
|
+
:bio => user.try(:bio) || user.try(:about),
|
42
|
+
:name => {
|
43
|
+
:first_name => user.try(:first_name),
|
44
|
+
:last_name => user.try(:last_name),
|
45
|
+
}
|
46
|
+
}.merge defaults
|
47
|
+
end
|
48
|
+
|
49
|
+
# Public: Check the validity of the JWT that Livefyre sends with pull requests.
|
50
|
+
#
|
51
|
+
# Raises [JWT::DecodeError] if the token is invalid or missing.
|
52
|
+
def validate_livefyre_request!
|
53
|
+
token = JWT.decode params[:lftoken], Livefyre.client.key
|
54
|
+
raise JWT::DecodeError unless token["domain"] == Livefyre.client.host
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|