canvas_lti_third_party_cookies 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -15
- data/Rakefile +2 -0
- data/app/assets/javascripts/canvas_lti_third_party_cookies/relaunch_on_login.js +66 -0
- data/app/assets/stylesheets/canvas_lti_third_party_cookies/relaunch_on_login.css +52 -0
- data/app/controllers/concerns/canvas_lti_third_party_cookies/relaunch_on_login.rb +71 -0
- data/app/views/canvas_lti_third_party_cookies/_cookie_message.erb +11 -0
- data/app/views/canvas_lti_third_party_cookies/relaunch_on_login.erb +41 -0
- data/lib/canvas_lti_third_party_cookies/engine.rb +4 -0
- data/lib/canvas_lti_third_party_cookies/version.rb +1 -1
- metadata +11 -8
- data/app/controllers/concerns/canvas_lti_third_party_cookies/safari_launch.rb +0 -60
- data/app/views/canvas_lti_third_party_cookies/prep_for_full_window_launch.erb +0 -99
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfadd9bf819df5cfb7740b3b1c88f7436337b0bafbc243d9df216af7e948cd9e
|
4
|
+
data.tar.gz: 6a539c02d809cbffbc9693a69567942af8ba24d839299d0baca93e3ebe1ef676
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a346aec85ae07519abe21496dbec0126bab0ab6ffc96de0d0b7c23be9eea02080cde3b7949295b598e9827c597442d83f866c758f0790a5bfad4da4faa4821cb
|
7
|
+
data.tar.gz: 9fb2fbc396790aca7e388e430adcd36ff2b2acf5d3f94309413e732b1ad354fdac8ee76197f1b3e74948ac59731cc10cbd3c931968361d0d6d3176c0e4af8a73
|
data/README.md
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# canvas_lti_third_party_cookies
|
2
2
|
|
3
|
-
Safari blocks all 3rd-party cookies by default, which breaks LTI tools that rely on setting cookies when launched in an iframe. Instead, it exposes a new API for getting user-permitted access to set cookies from an iframe, which unfortunately doesn't completely work for LTI use cases.
|
3
|
+
Safari blocks all 3rd-party cookies by default, which breaks LTI tools that rely on setting cookies when launched in an iframe. Other browsers will soon follow suit. Instead, it exposes a new API for getting user-permitted access to set cookies from an iframe, which unfortunately doesn't completely work for LTI use cases.
|
4
4
|
See this article for a detailed explanation of the Storage Access API and previous attempts to launch LTI tools in Safari: https://community.canvaslms.com/t5/Developers-Group/Safari-13-1-and-LTI-Integration/ba-p/273051
|
5
5
|
|
6
|
-
The current workaround that this gem implements is to relaunch the tool in a new tab, new window, or popup window, where it can set first-party cookies to it's heart's content.
|
7
|
-
does here: https://github.com/instructure/canvas-lms/blob/master/public/javascripts/lti/post_message/requestFullWindowLaunch.js
|
6
|
+
The current workaround that this gem implements is to relaunch the tool in a new tab, new window, or popup window, where it can set first-party cookies to it's heart's content. The relaunch occurs during the login request, so the tool is entirely in control, and no other parts of the LTI launch flow are modified.
|
8
7
|
|
9
8
|
## Installation
|
10
9
|
Add this line to your application's Gemfile:
|
@@ -24,18 +23,41 @@ $ bundle install
|
|
24
23
|
Choose the Rails controller action that's used to launch your tool and set cookies. Set the before_action callback
|
25
24
|
below to run on that action, and pass the data needed.
|
26
25
|
|
27
|
-
* `
|
28
|
-
* `
|
29
|
-
|
30
|
-
* `
|
26
|
+
* `redirect_url` (required): the authorization redirect URL to continue the login flow
|
27
|
+
* `redirect_data` (required): all form data required for the authorization redirect, which
|
28
|
+
the previous login render call should have included in a form tag.
|
29
|
+
* `window_type`: (optional) Set to `:new_window` to open the tool in a
|
30
|
+
new tab or window, or to `:popup` to open in a popup window.
|
31
|
+
Defaults to `:new_window`.
|
32
|
+
* `width`: (optional) The width the popup window should be, in px. User
|
33
|
+
has the discretion to ignore this. Only valid with window_type: popup.
|
34
|
+
Defaults to 800px.
|
35
|
+
* `height`: (optional) The height the popup window should be, in px. User
|
36
|
+
has the discretion to ignore this. Only valid with window_type: popup.
|
37
|
+
Defaults to 600px.
|
31
38
|
|
39
|
+
example:
|
32
40
|
```ruby
|
33
|
-
include CanvasLtiThirdPartyCookies::
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
41
|
+
include CanvasLtiThirdPartyCookies::RelaunchOnLogin
|
42
|
+
...
|
43
|
+
def login
|
44
|
+
state, nonce = create_and_cache_state # handled elsewhere
|
45
|
+
redirect_url = 'http://canvas.instructure.com/api/lti/authorize_redirect'
|
46
|
+
redirect_data = {
|
47
|
+
scope: 'openid',
|
48
|
+
response_type: 'id_token',
|
49
|
+
response_mode: 'form_post',
|
50
|
+
prompt: 'none',
|
51
|
+
redirect_uri: redirect_uri, # the launch url of the tool
|
52
|
+
client_id: params.require(:client_id),
|
53
|
+
login_hint: params.require(:login_hint),
|
54
|
+
lti_message_hint: params.require(:lti_message_hint),
|
55
|
+
state: state,
|
56
|
+
nonce: nonce
|
57
|
+
}
|
58
|
+
|
59
|
+
relaunch_on_login(redirect_url, redirect_data)
|
60
|
+
end
|
39
61
|
```
|
40
62
|
|
41
63
|
## Testing
|
@@ -47,7 +69,7 @@ $ rails test
|
|
47
69
|
## Publishing New Versions
|
48
70
|
|
49
71
|
1. Bump the version in `lib/canvas_lti_third_party_cookies/version.rb`.
|
50
|
-
2.
|
51
|
-
3.
|
72
|
+
2. `rake install`
|
73
|
+
3. Commit, push, and merge that change.
|
52
74
|
4. `gem push pkg/canvas_lti_third_party_cookies-<version>.gem`
|
53
75
|
- note that this will only work if you have access
|
data/Rakefile
CHANGED
@@ -0,0 +1,66 @@
|
|
1
|
+
document.addEventListener("DOMContentLoaded", () => {
|
2
|
+
const { window_type, form_target, width, height } = window.ENV;
|
3
|
+
|
4
|
+
let newWindow;
|
5
|
+
const openNewWindow = () => {
|
6
|
+
switch (window_type) {
|
7
|
+
case "popup": {
|
8
|
+
newWindow = window.open(
|
9
|
+
"",
|
10
|
+
form_target,
|
11
|
+
"toolbar=no,menubar=no,location=no,status=no,resizable,scrollbars," +
|
12
|
+
`width=${width},height=${height}`
|
13
|
+
);
|
14
|
+
break;
|
15
|
+
}
|
16
|
+
case "new_window": {
|
17
|
+
newWindow = window.open("", form_target);
|
18
|
+
break;
|
19
|
+
}
|
20
|
+
}
|
21
|
+
};
|
22
|
+
|
23
|
+
const getRelaunchElement = (id) => document.getElementById(`relaunch-${id}`);
|
24
|
+
const hide = (el) => (el.style.display = "none");
|
25
|
+
const show = (el) => (el.style.display = "flex"); // normally this is 'block', but the containers need to be 'flex'
|
26
|
+
|
27
|
+
const successMessageEl = getRelaunchElement("success");
|
28
|
+
const retryMessageEl = getRelaunchElement("retry");
|
29
|
+
const relaunchFormEl = getRelaunchElement("form");
|
30
|
+
const retryButtonEl = getRelaunchElement("request");
|
31
|
+
|
32
|
+
// set a test cookie
|
33
|
+
const testCookie = "canSetCookies=true";
|
34
|
+
document.cookie = testCookie;
|
35
|
+
if (
|
36
|
+
document.cookie.split(";").some((cookie) => cookie.includes(testCookie))
|
37
|
+
) {
|
38
|
+
// setting cookies works, continue login flow inline
|
39
|
+
// todo: remove test cookie
|
40
|
+
document.getElementById("redirect-form").submit();
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
|
44
|
+
// open in new tab and restart login flow
|
45
|
+
show(successMessageEl);
|
46
|
+
openNewWindow();
|
47
|
+
|
48
|
+
if (newWindow) {
|
49
|
+
// tool opened successfully, POST login form data to opened window
|
50
|
+
relaunchFormEl.submit();
|
51
|
+
return;
|
52
|
+
}
|
53
|
+
|
54
|
+
// tool open blocked, tell user to allow popups and try again
|
55
|
+
show(retryMessageEl);
|
56
|
+
hide(successMessageEl);
|
57
|
+
|
58
|
+
retryButtonEl.addEventListener("click", () => {
|
59
|
+
// open tool and POST login data again
|
60
|
+
openNewWindow();
|
61
|
+
relaunchFormEl.submit();
|
62
|
+
|
63
|
+
show(successMessageEl);
|
64
|
+
hide(retryMessageEl);
|
65
|
+
});
|
66
|
+
});
|
@@ -0,0 +1,52 @@
|
|
1
|
+
.flex-container {
|
2
|
+
display: none;
|
3
|
+
flex-direction: column;
|
4
|
+
height: 100%;
|
5
|
+
font-family: "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans",
|
6
|
+
"Helvetica Neue", Arial, sans-serif;
|
7
|
+
font-size: 1.1em;
|
8
|
+
padding: 0 24px;
|
9
|
+
}
|
10
|
+
|
11
|
+
.flex-item {
|
12
|
+
margin-bottom: 10px;
|
13
|
+
text-align: center;
|
14
|
+
}
|
15
|
+
|
16
|
+
.flex-container div:first-child {
|
17
|
+
margin-top: 24px;
|
18
|
+
}
|
19
|
+
|
20
|
+
p {
|
21
|
+
margin: 0 0 0.5em 0;
|
22
|
+
}
|
23
|
+
|
24
|
+
button {
|
25
|
+
background: #008ee2;
|
26
|
+
color: #ffffff;
|
27
|
+
border: 1px solid;
|
28
|
+
border-color: #0079c1;
|
29
|
+
border-radius: 3px;
|
30
|
+
transition: background-color 0.2s ease-in-out;
|
31
|
+
display: inline-block;
|
32
|
+
position: relative;
|
33
|
+
padding: 8px 14px;
|
34
|
+
margin-bottom: 0;
|
35
|
+
font-size: 16px;
|
36
|
+
font-size: 1rem;
|
37
|
+
line-height: 20px;
|
38
|
+
text-align: center;
|
39
|
+
vertical-align: middle;
|
40
|
+
cursor: pointer;
|
41
|
+
text-decoration: none;
|
42
|
+
overflow: hidden;
|
43
|
+
text-shadow: none;
|
44
|
+
-webkit-user-select: none;
|
45
|
+
-moz-user-select: none;
|
46
|
+
user-select: none;
|
47
|
+
}
|
48
|
+
|
49
|
+
img {
|
50
|
+
width: 100px;
|
51
|
+
height: 100px;
|
52
|
+
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module CanvasLtiThirdPartyCookies::RelaunchOnLogin
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
# this should replace your previous login render call, at the end of your login action.
|
5
|
+
#
|
6
|
+
# `redirect_url` (required): the authorization redirect URL to continue the login flow
|
7
|
+
#
|
8
|
+
# `redirect_data` (required): all form data required for the authorization redirect, which
|
9
|
+
# the previous login render call should have included in a form tag.
|
10
|
+
#
|
11
|
+
# `window_type`: (optional) Set to `:new_window` to open the tool in a
|
12
|
+
# new tab or window, or to `:popup` to open in a popup window.
|
13
|
+
# Defaults to `:new_window`.
|
14
|
+
#
|
15
|
+
# `width`: (optional) The width the popup window should be, in px. User
|
16
|
+
# has the discretion to ignore this. Only valid with window_type: popup.
|
17
|
+
# Defaults to 800px.
|
18
|
+
#
|
19
|
+
# `height`: (optional) The height the popup window should be, in px. User
|
20
|
+
# has the discretion to ignore this. Only valid with window_type: popup.
|
21
|
+
# Defaults to 600px.
|
22
|
+
#
|
23
|
+
# example:
|
24
|
+
# include CanvasLtiThirdPartyCookies::RelaunchOnLogin
|
25
|
+
# ...
|
26
|
+
# def login
|
27
|
+
# state, nonce = create_and_cache_state # handled elsewhere
|
28
|
+
# redirect_url = 'http://canvas.instructure.com/api/lti/authorize_redirect'
|
29
|
+
# redirect_data = {
|
30
|
+
# scope: 'openid',
|
31
|
+
# response_type: 'id_token',
|
32
|
+
# response_mode: 'form_post',
|
33
|
+
# prompt: 'none',
|
34
|
+
# redirect_uri: redirect_uri, # the launch url of the tool
|
35
|
+
# client_id: params.require(:client_id),
|
36
|
+
# login_hint: params.require(:login_hint),
|
37
|
+
# lti_message_hint: params.require(:lti_message_hint),
|
38
|
+
# state: state,
|
39
|
+
# nonce: nonce
|
40
|
+
# }
|
41
|
+
#
|
42
|
+
# relaunch_on_login(redirect_url, redirect_data)
|
43
|
+
# end
|
44
|
+
def relaunch_on_login(redirect_url, redirect_data, window_type: :new_window, width: 800, height: 600)
|
45
|
+
raise ArgumentError.new("window_type must be either :new_window or :popup") unless [:new_window, :popup].include? window_type
|
46
|
+
|
47
|
+
window_type_text = {
|
48
|
+
new_window: 'new tab',
|
49
|
+
popup: 'popup window'
|
50
|
+
}
|
51
|
+
form_target = 'login_relaunch'
|
52
|
+
|
53
|
+
render(
|
54
|
+
'canvas_lti_third_party_cookies/relaunch_on_login',
|
55
|
+
locals: {
|
56
|
+
redirect_url: redirect_url,
|
57
|
+
redirect_data: redirect_data,
|
58
|
+
relaunch_url: request.url,
|
59
|
+
relaunch_data: params.permit(:canvas_region, :client_id, :iss, :login_hint, :lti_message_hint, :target_link_uri),
|
60
|
+
form_target: form_target,
|
61
|
+
window_type_text: window_type_text[window_type],
|
62
|
+
js_env: {
|
63
|
+
form_target: form_target,
|
64
|
+
window_type: window_type,
|
65
|
+
width: width,
|
66
|
+
height: height
|
67
|
+
}
|
68
|
+
}
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<div id="<%= id %>" class="flex-container">
|
2
|
+
<div class="flex-item">
|
3
|
+
<img src="https://upload.wikimedia.org/wikipedia/commons/0/03/Oxygen480-apps-preferences-web-browser-cookies.svg" alt="Cookie" />
|
4
|
+
</div>
|
5
|
+
|
6
|
+
<div class="flex-item">
|
7
|
+
<strong>It looks like your browser doesn't like cookies.</strong>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<%= yield %>
|
11
|
+
</div>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<%= stylesheet_link_tag 'canvas_lti_third_party_cookies/relaunch_on_login' %>
|
2
|
+
<%= javascript_tag do %>
|
3
|
+
window.ENV = <%= js_env.to_json.html_safe %>
|
4
|
+
<% end %>
|
5
|
+
<%= javascript_include_tag 'canvas_lti_third_party_cookies/relaunch_on_login' %>
|
6
|
+
|
7
|
+
<%# when submitted, continue to login flow step 2: redirect back to Canvas for authentication %>
|
8
|
+
<%= form_tag(redirect_url, method: :post, id: 'redirect-form') do %>
|
9
|
+
<% redirect_data.each do |k, v| %>
|
10
|
+
<%= hidden_field_tag(k, v) %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%# when submitted, replay login flow step 1 in a new window %>
|
15
|
+
<%# the target attribute tells the form to POST in the window matching that target, which is opened below %>
|
16
|
+
<%= form_tag(relaunch_url, method: :post, id: 'relaunch-form', target: form_target) do %>
|
17
|
+
<% relaunch_data.each do |k, v| %>
|
18
|
+
<%= hidden_field_tag(k, v) %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<%# default message to display on new window launch; hidden by default %>
|
23
|
+
<%= render 'canvas_lti_third_party_cookies/cookie_message', id: 'relaunch-success' do %>
|
24
|
+
<div class="flex-item">
|
25
|
+
<p>Some browsers block third-party cookies by default, which this app relies on for launch and sign-in features.</p>
|
26
|
+
<p>This app has opened in a <%= window_type_text %>, so that it can set its own cookies.
|
27
|
+
</div>
|
28
|
+
<% end %>
|
29
|
+
|
30
|
+
<%# message displayed when popups are blocked; hidden by default %>
|
31
|
+
<%= render 'canvas_lti_third_party_cookies/cookie_message', id: 'relaunch-retry' do %>
|
32
|
+
<div class="flex-item">
|
33
|
+
<p>Some browsers block third-party cookies by default, which this app relies on for launch and sign-in features.</p>
|
34
|
+
<p>Launching this app in a <%= window_type_text %>, separate from Canvas, will allow the app to set its own cookies.</p>
|
35
|
+
<p>To open the app, make sure your browser allows popups for this page and try again.</p>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<div class="flex-item">
|
39
|
+
<button id="relaunch-request">Open in <%= window_type_text.capitalize %></button>
|
40
|
+
</div>
|
41
|
+
<% end %>
|
@@ -1,5 +1,9 @@
|
|
1
1
|
module CanvasLtiThirdPartyCookies
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
isolate_namespace CanvasLtiThirdPartyCookies
|
4
|
+
|
5
|
+
initializer "CanvasLtiThirdPartyCookies.assets.precompile" do |app|
|
6
|
+
app.config.assets.precompile += %w( canvas_lti_third_party_cookies/relaunch_on_login.js canvas_lti_third_party_cookies/relaunch_on_login.css )
|
7
|
+
end
|
4
8
|
end
|
5
9
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: canvas_lti_third_party_cookies
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xander Moffatt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0.
|
19
|
+
version: 6.0.3
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 6.0.
|
22
|
+
version: 6.0.3.6
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 6.0.
|
29
|
+
version: 6.0.3
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 6.0.
|
32
|
+
version: 6.0.3.6
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: browser
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,8 +75,11 @@ files:
|
|
75
75
|
- LICENSE
|
76
76
|
- README.md
|
77
77
|
- Rakefile
|
78
|
-
- app/
|
79
|
-
- app/
|
78
|
+
- app/assets/javascripts/canvas_lti_third_party_cookies/relaunch_on_login.js
|
79
|
+
- app/assets/stylesheets/canvas_lti_third_party_cookies/relaunch_on_login.css
|
80
|
+
- app/controllers/concerns/canvas_lti_third_party_cookies/relaunch_on_login.rb
|
81
|
+
- app/views/canvas_lti_third_party_cookies/_cookie_message.erb
|
82
|
+
- app/views/canvas_lti_third_party_cookies/relaunch_on_login.erb
|
80
83
|
- app/views/layouts/application.html.erb
|
81
84
|
- lib/canvas_lti_third_party_cookies.rb
|
82
85
|
- lib/canvas_lti_third_party_cookies/engine.rb
|
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'browser'
|
2
|
-
|
3
|
-
module CanvasLtiThirdPartyCookies::SafariLaunch
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
# this needs to be called as a before_action on the route that launches the tool
|
7
|
-
# and the tool is required to pass some parameters to this method.
|
8
|
-
#
|
9
|
-
# `placement`: (required) Should be the Canvas placement that
|
10
|
-
# the tool was launched from, taken from the decoded id_token's
|
11
|
-
# `https://www.instructure.com/placement` claim.
|
12
|
-
#
|
13
|
-
# `window_type`: (optional) Set to `:new_window` to open the tool in a
|
14
|
-
# new tab or window, or to `:popup` to open in a popup window.
|
15
|
-
# Defaults to `:new_window`.
|
16
|
-
#
|
17
|
-
# `width`: (optional) The width the popup window should be, in px. User
|
18
|
-
# has the discretion to ignore this. Only valid with window_type: popup.
|
19
|
-
# Defaults to 800px.
|
20
|
-
#
|
21
|
-
# `height`: (optional) The height the popup window should be, in px. User
|
22
|
-
# has the discretion to ignore this. Only valid with window_type: popup.
|
23
|
-
# Defaults to 600px.
|
24
|
-
#
|
25
|
-
# example:
|
26
|
-
# include CanvasLtiThirdPartyCookies::SafariLaunch
|
27
|
-
# ...
|
28
|
-
# before_action -> {
|
29
|
-
# placement = decoded_id_token['https://www.instructure.com/placement']
|
30
|
-
# handle_safari_launch(placement: placement, window_type: :popup)
|
31
|
-
# }
|
32
|
-
def handle_safari_launch(placement:, window_type: :new_window, width: nil, height: nil)
|
33
|
-
raise ArgumentError.new("window_type must be either :new_window or :popup") unless [:new_window, :popup].include? window_type
|
34
|
-
return unless is_safari?
|
35
|
-
return if is_full_window_launch?
|
36
|
-
|
37
|
-
render(
|
38
|
-
'canvas_lti_third_party_cookies/prep_for_full_window_launch',
|
39
|
-
locals: {
|
40
|
-
launch_url: request.base_url + request.fullpath,
|
41
|
-
placement: placement,
|
42
|
-
window_type: window_type.to_s,
|
43
|
-
width: width || 800,
|
44
|
-
height: height || 600
|
45
|
-
}
|
46
|
-
)
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def is_full_window_launch?
|
52
|
-
params[:full_win_launch_requested].present?
|
53
|
-
end
|
54
|
-
|
55
|
-
def is_safari?
|
56
|
-
browser = Browser.new(request.headers["User-Agent"])
|
57
|
-
# detect both MacOS and iOS Safari
|
58
|
-
browser.safari? || (browser.webkit? && browser.platform.ios?)
|
59
|
-
end
|
60
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
<%= javascript_tag do -%>
|
2
|
-
const requestFullWindowLaunch = () => {
|
3
|
-
console.log("clicked")
|
4
|
-
window.parent.postMessage(
|
5
|
-
{
|
6
|
-
messageType: "requestFullWindowLaunch",
|
7
|
-
data: {
|
8
|
-
url: "<%= launch_url %>",
|
9
|
-
placement: "<%= placement %>",
|
10
|
-
launchType: "<%= window_type %>",
|
11
|
-
launchOptions: {
|
12
|
-
width: <%= width %>,
|
13
|
-
height: <%= height %>
|
14
|
-
}
|
15
|
-
}
|
16
|
-
},
|
17
|
-
"*"
|
18
|
-
);
|
19
|
-
};
|
20
|
-
document.addEventListener("DOMContentLoaded", () => {
|
21
|
-
console.log("loaded")
|
22
|
-
document.getElementById("request").addEventListener("click", requestFullWindowLaunch)
|
23
|
-
});
|
24
|
-
<% end %>
|
25
|
-
<style type="text/css">
|
26
|
-
.flex-container {
|
27
|
-
display: flex;
|
28
|
-
flex-direction: column;
|
29
|
-
height: 100%;
|
30
|
-
font-family: "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif;
|
31
|
-
font-size: 1.1em;
|
32
|
-
padding: 0 24px;
|
33
|
-
}
|
34
|
-
|
35
|
-
.flex-item {
|
36
|
-
margin-bottom: 10px;
|
37
|
-
text-align: center;
|
38
|
-
}
|
39
|
-
|
40
|
-
.flex-container div:first-child {
|
41
|
-
margin-top: 24px;
|
42
|
-
}
|
43
|
-
|
44
|
-
p {
|
45
|
-
margin: 0 0 0.5em 0;
|
46
|
-
}
|
47
|
-
|
48
|
-
button {
|
49
|
-
background: #008EE2;
|
50
|
-
color: #ffffff;
|
51
|
-
border: 1px solid;
|
52
|
-
border-color: #0079C1;
|
53
|
-
border-radius: 3px;
|
54
|
-
transition: background-color 0.2s ease-in-out;
|
55
|
-
display: inline-block;
|
56
|
-
position: relative;
|
57
|
-
padding: 8px 14px;
|
58
|
-
margin-bottom: 0;
|
59
|
-
font-size: 16px;
|
60
|
-
font-size: 1rem;
|
61
|
-
line-height: 20px;
|
62
|
-
text-align: center;
|
63
|
-
vertical-align: middle;
|
64
|
-
cursor: pointer;
|
65
|
-
text-decoration: none;
|
66
|
-
overflow: hidden;
|
67
|
-
text-shadow: none;
|
68
|
-
-webkit-user-select: none;
|
69
|
-
-moz-user-select: none;
|
70
|
-
}
|
71
|
-
|
72
|
-
#safari-logo {
|
73
|
-
width: 100px;
|
74
|
-
height: 100px;
|
75
|
-
}
|
76
|
-
</style>
|
77
|
-
|
78
|
-
<div class="flex-container">
|
79
|
-
<div class="flex-item">
|
80
|
-
<img id="safari-logo" src="https://upload.wikimedia.org/wikipedia/commons/5/52/Safari_browser_logo.svg" alt="Safari Logo" />
|
81
|
-
</div>
|
82
|
-
|
83
|
-
<div class="flex-item">
|
84
|
-
<strong>It looks like you are using Safari.</strong>
|
85
|
-
</div>
|
86
|
-
|
87
|
-
<div class="flex-item">
|
88
|
-
<p>Safari blocks third-party cookies by default, which this app relies on for sign-in features.</p>
|
89
|
-
<p>Launching this app in a <%if window_type == "popup"%>popup window<%else%>new tab<%end%>, separate from Canvas, will allow the app to set its own cookies.</p>
|
90
|
-
<%if window_type == "popup"%>
|
91
|
-
<p>If the app doesn't appear, make sure Safari is not blocking popups.</p>
|
92
|
-
<%end%>
|
93
|
-
</div>
|
94
|
-
|
95
|
-
<div class="flex-item">
|
96
|
-
<button id="request">Open <%if window_type == "popup"%>Popup<%else%>in New Tab<%end%></button>
|
97
|
-
</div>
|
98
|
-
<div>
|
99
|
-
</div>
|