cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
kbeimfohr
Advocate

Embedding Remind Widget into Course Page

Jump to solution

I am trying to embed a Remind widget into my course page.  I go to the HTML Editor and paste the code they gave me:

<script src="https://widgets.remind.com/iframe.js?token=3d3bfc90e5d3013277eb3f9249bd17cc"></script>

When I save it, the page is empty.  If I go back to edit the code again, it is not there.  It appears that it isn't saving the code.  Can anyone help me figure out how to embed the code so the Remind feed will show up on the page, similar to a twitter widget feed?  Thanks!

1 Solution
James
Community Champion

kbeimfohr​,

The <script> tag is not allowed inside of Canvas pages. A list of acceptable tags is at https://s3.amazonaws.com/tr-learncanvas/docs/Canvas_HTML_Whitelist.pdf

The decision to keep users from running <script> tags has lots of reasoning behind it. Foremost is security. Allowing external scripts to run on the page within Canvas would allow the script writer to potentially run things with the permissions of the user and definitely expose information that shouldn't be exposed.

To do this kind of thing, you'll need to use an iframe. I notice the page you call creates its own iframe, but to get Canvas to call it, you need to put an iframe into Canvas with a src of the page you want to load.

Pasting the script you provided as the source doesn't work. It just provides the source of the javascript within the window.

However, what you need to do is pretty simple. I don't use remind.com, but I was able to take your code and get it to work in my Canvas sandbox.

Go into the HTML editor on the page and then paste this code. I got the code from inside the script you had listed. Feel free to change the height and width:

<iframe src="https://r101-widgets.herokuapp.com/3d3bfc90e5d3013277eb3f9249bd17cc" width="600" height="150"></iframe>

This is what it looks like (the iframe test kyle was the page name I used in Canvas).

kyle_remind-com.png

By the way, I don't know how sensitive that token is, but you may want to change your token now that you've posted it on the Internet. Or maybe not, maybe you'll have lots of people following your reminders.

View solution in original post

17 Replies
James
Community Champion

kbeimfohr​,

The <script> tag is not allowed inside of Canvas pages. A list of acceptable tags is at https://s3.amazonaws.com/tr-learncanvas/docs/Canvas_HTML_Whitelist.pdf

The decision to keep users from running <script> tags has lots of reasoning behind it. Foremost is security. Allowing external scripts to run on the page within Canvas would allow the script writer to potentially run things with the permissions of the user and definitely expose information that shouldn't be exposed.

To do this kind of thing, you'll need to use an iframe. I notice the page you call creates its own iframe, but to get Canvas to call it, you need to put an iframe into Canvas with a src of the page you want to load.

Pasting the script you provided as the source doesn't work. It just provides the source of the javascript within the window.

However, what you need to do is pretty simple. I don't use remind.com, but I was able to take your code and get it to work in my Canvas sandbox.

Go into the HTML editor on the page and then paste this code. I got the code from inside the script you had listed. Feel free to change the height and width:

<iframe src="https://r101-widgets.herokuapp.com/3d3bfc90e5d3013277eb3f9249bd17cc" width="600" height="150"></iframe>

This is what it looks like (the iframe test kyle was the page name I used in Canvas).

kyle_remind-com.png

By the way, I don't know how sensitive that token is, but you may want to change your token now that you've posted it on the Internet. Or maybe not, maybe you'll have lots of people following your reminders.

This doesn't seem to work any more. I've tried several times to embed the remind widget using https://community.canvaslms.com/thread/2815 Kyle's code and it disappears (I insert my own widget code minus the script part and using the iframe code that Kyle provided). Can anyone still make this work?

I'm not using the widget, but for what it's worth, the widgets.remind.com subdomain seems to be unavailable:

http://widgets.remind.com/ 

I don't know anything about remind.com, but I would guess their technical support would be the place to find out what has happened with their widget service.

Matthew,

Were you able to get it to work?  I just successfully tested using the code converter created by the St. Mark's Team.

https://helpdesk.stmarksschool.org/how-do-i-embed-a-remind-com-widget-in-canvas/#comment-7611 

My husband works for Remind so I'm helping him in researching use cases and demand for a deeper Remind integration into Canvas.

Thanks!

Kristin

Dixon Charter Montessori School

laurakgibbs
Community Champion

As someone who was used to using D2L (we had it at my school for 10 years, and I used javascripts in D2L with no problem), I was surprised that instructors are not trusted to use scripts in our Canvas spaces (it makes it feel much less like "my" space if I cannot use scripts there)... so I've also had to use the iframe workaround In terms of design, iframe is a clunky solution (layout, css problems), but what I've been doing is creating vanilla webpages in my own webspace, and then using iframes to display the results.

So, for example, here is how I am running my own javascript widgets:

Laura's Widget Warehouse: Homepage: Laura's Widget Warehouse 

And I started using the same trick for Twitter widgets (real ones):

OU Daily Twitter Stream: Twitter4Canvas 

And I just discovered that this also fixes the (broken) Flickr album embeds in a Canvas page:

Flickr Album: CanvasLIVE Playground 

But here's what I don't understand about the supposed security argument: if I take an html file that contains a script and upload that html file to my "Files" space in Canvas, and then view that file, the script runs. .

But if I paste that exact same identical script into a Canvas Page, the Page editor strips it out.

Here's an example: this html file contains a javascript, and when I upload that file into my Canvas File area, the script runs exactly as expected (item displays at random)... but when I attempt to paste that same script into a Canvas Page, it gets stripped.

I don't understand why it is a security risk in a Page, but not in a File...?

Canvas file screenshot

This is the script call getting stripped from the Page but which is running in the uploaded file:

<script type="text/javascript"> var display = "random" </script><script type="text/javascript" src="https://widgets.lauragibbs.net/fb/india400.js"></script>

laurakgibbs,

Let me start with I saw some of your stuff the other day and visited your site and saw your widgets page. I was especially intrigued by your teacher-does-no-grading approach. Anyway, I don't want to hijack the thread, just wanted to say you've done a lot of interesting things and are doing a wonderful job documenting it for other people.

I'll also have to say I cringed when I read your statements about using widgets with other learning management systems and not understanding why Canvas won't allow it. Hopefully this message will help clear up the reasoning. I'll also say that I'm not a Canvas employee, although I do enjoy their conferences, and they probably have reasoning that goes far beyond anything I can suppose. And while I know a little about security, there are other people much more knowledgeable than I am that could probably provide a more in-depth explanation.

I'm not a tl;dr kind of guy (I think there's a meme somewhere about that), but the short version is:

The file that you uploaded with JavaScript in it is not the security issue when viewed from within Files that it is when viewed from a Content Page. Therefore, Canvas does not need to sanitize it within the Files section, but they do for Content Pages.

Here is an example file I created.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML File with JavaScript Embedded</title>
  <script>
    alert('I am clever and will hijack your system.');
    console.log(ENV);
  </script>

</head>
<body>
<h1>HTML File with JavaScript Embedded</h1>
  <p>This is an HTML file with a JavaScript script embedded in it</p>
</body>
</html>

The alert() just pops a message up on the browser window and waits. The console.log() sends a message to the browser's console log, which can be seen in most browsers with F12. I use it a lot for debugging things, but in production it probably shouldn't be used. I used those two commands to do some JavaScript without actually doing any damage.

The ENV variable that's it's logging to the Console is part of the environment that is exposed by Canvas when you are inside Canvas. It includes things like your timezone, your name, your user ID, certain features that are enabled, etc. It's not so much the information that's contained in there as the fact that you can see it that is worrisome. If you can see that and you can run JavaScript on the page, then you can do things as that user without any further steps. I do quite a bit of this with the user script Canvancements that I write. Things like sorting the roster, downloading the access information for an entire class, or the rubric importer I just released on Monday.

If a script was poorly written, and many are (we've probably all seen the "this page is unresponsive" errors), then allowing it to run on the page could make Canvas unresponsive or slow. The user isn't going to blame the script that the instructor put on the page for the problem, they just know it happened in Canvas, so Canvas is going to get the blame. By requiring custom JavaScript to be added at the account or sub-account level, they're hoping that the code has been vetted and checked, rather than just some widget that someone found on the internet and it looks cool but they don't code themselves so they didn't check it out to make sure it was safe.

If you were malicious, you could do other things, like automatically submit a quiz and keep the user from being able to turn things in. You could set it to change the password so the person couldn't log in or change it to something so you could log in and then do anything you wanted as that student. If you're a prankster more than someone malicious, you could change the language so they couldn't read anything on the page. You could hijack their communications and send out emails to everyone in their courses and get the real owner banned. You could set it to display pop-ups of advertising or warn that your computer is infected and you'll need to send money to get it restored to normal. If someone viewed the page (or file) who had elevated rights, like an admin, then real damage could be done. The malicious person could go through and start deleting files, pages, or even courses. And while there is the wonderful /undelete route for most things, this could cause serious disruption.

In other words, my console.log() could have easily been malicious code and that's part of why Canvas doesn't allow it on content pages. A teacher might never do that, but a student could easily insert something into a discussion post and then anyone who views the discussion would be hit with whatever payload it had.

Now to talk about files.

Here's that file I wrote sitting in my files folder of my sandbox course on my beta instance of Canvas.

217694_pastedImage_1.png

When I click on it I get this

217698_pastedImage_5.png

The alert() function is actually blocking, which means that execution stops at that point, which is why the rest of the page did get loaded until I click the OK (I did this to make the point about poorly written code could cause problems). After I clicked OK, then I got the rest of the page to show.

217697_pastedImage_4.png

If I look at my browser's console log (F12) with the JavaScript errors enabled, I get this:

217699_pastedImage_6.png

However, if I manually ask it to show the ENV variable, I get

217700_pastedImage_7.png

The ReferenceError: ENV is not defined happens because you're not actually inside the Canvas environment when you're viewing that file.

To the normal user, that last sentence is absurd sounding because they can see the Canvas menu and they clicked on the file from within Canvas, so in their mind, they're in Canvas. That's why it's so important that Canvas not allow scripts -- it's a trusted environment. Users are going to trust anything it does because the school said to use it. If a message pops up within Canvas that says "There has been a problem with your financial aid -- enter your SSN and credit card information so we can fix the problem." some students are going to fall for it.

But if you look at the code using the inspector, you'll see something like this:

217702_pastedImage_10.png

Yes, that's an iframe that the document is wrapped inside. The iframe provides isolation from the parent window (the Canvas application) so that it can't interact with it (there are scripts that allow this, but they're not loaded unless someone has modified their custom JavaScript - H5P suggests doing this with their content).

The parent window (Canvas) can see the contents of the iFrame, and I use that in my QuizWiz user script so that I can add buttons to the page that's loaded to speed up the process. But the iframe can't see the parent, which is why people keep on asking if there's any way to resize embedded content, like SCORM, to make it take up the entire screen instead of being stuck in the pre-defined size that is too small to be usable or adds scrollbars if set too large.

It's a good thing that the content is contained within an iframe because it would be very difficult for Canvas to scan the contents of a file for malicious content -- that would be like having a built-in virus checker, which has been a feature request if I remember correctly. Antivirus definitions files are changed multiple times throughout the day and even though I scan my email attachments folder when the files are downloaded and again every morning, it's often a few days or weeks before the virus is detected. Inside an HTML file, the JavaScript could be obfuscated, minimized, or otherwise altered so that it doesn't appear malicious until it actually runs. It's really going to be difficult to impossible to protect against that while running in the Canvas environment and not an iframe, so it's safest to use the iframe. On the other hand, the content in a content page is much easier to handle since it needs to be HTML and for accessibility purposes, it needs to be well-formed HTML. Canvas can strip out the things that are known to be bad or potentially dangerous, or better yet, allow just the things that are known to work well. That's better from a security perspective because a list of blocked elements might miss something or a vulnerability might be found that wasn't on the original list and cause a rush to get it handled before it does damage; whereas a list of allowed elements says these are known to be safe. Only allowing certain things to be changed by the designer/instructor is also good for the consistent look and feel of the Canvas environment, which in turn helps students. (Yesterday, I watched Jared Stein's Ask Me Anything presentation and I feel like I just went through five levels of why -- even things that hadn't quite gelled for me became all the more apparent as I wrote this).

In summary:

Including scripts is a security risk on a content page because it's part of the actual page and runs within a Canvas environment with the permissions of the user logged into Canvas and could cause serious problems if it were allowed. Canvas is right to strip out script tags at that point for the protection of the users and the environment.

However, when previewing the file, it's wrapped inside an iFrame tag and so it's in its own browser environment and can't get access to the Canvas environment. You could still do annoying things like pop-up messages telling student that their account has been hijacked, but it wouldn't be able to take over and do things as that student within Canvas.

You only mentioned viewing files from the Files page, but I did go ahead and use the Content Selector to add a link to the file inside a page and inside a quiz. The link returns you to the Files page where it is embedded within an iframe and protected from bad scripts.

Oh my gosh, THIS IS FASCINATING. I always thought of iframe as just a display trick, and I had never wondered just how it fit into the overall security of a page. Thank you so much,  @James ‌ : now I am doubly in your debt (for your magical API/Sheet solution to quiz updates and now for this)... The power of why! 

Let me then ask one more question, which is about File Preview. The File Preview comes with an iframe wrapper that keeps the script processing safe... but it also comes up with other stuff too (the black border, the file name, the navigation panel, etc.) in addition to the contents that I uploaded myself as the contents of the file.

So if I just use that Preview URL, I cannot iframe my own File inside a Canvas Page, using the URL I see in the browser bar: files?preview=3820356

But is there some other way to query the file contents so that I do not get everything that is being displayed, but just my own contents. What I mean is this: I would like to be able to iframe my own File in a Page, as at this URL:

Canvas (I framed the files?preview=3820356 version of the file which is what I get when I click on the link in the File listing that I see in Canvas)

It's not just an idle request, I promise. The reason I am asking is that if, say, people create a widget using RotateContent.com or using the widgets from Twitter.com or the embedded slideshow from Flickr (as in my examples above), to make the https/iframe trick work, they have to have their OWN https webspace somewhere to put the thing so that they can iframe it. And using iframe is not great (display issues mentioned above), but it's okay. Here's the real problem: I know not everybody has ready access to their own https webspace (I have it at my school through the great Domains project of Reclaim Hosting)... so, what I'd like to find out is if people can upload a javascript as part of a File in Canvas, and then iframe the contents of that file only, not the whole File Preview.

Perhaps the answer is already there in what you said but I could not see for myself; the HTML source for a File Preview page was so enormous (almost 400 lines), and I am not a coder myself, so I didn't really even know where to look for my uploaded file contents inside that page. So, is there a way for me to get access to a "vanilla" view of this file apparently numbered 3820356 so that I can iframe THAT file (the one I uploaded):

Files  (this is how the file displays in Preview mode)

Which iframes like this if I use the preview query:

Canvas  (see screenshot below)

in exactly the same way I am iframing the file I have in my own https webspace here: 

Canvas: Freebookapalooza — India 

I hope you will forgive me if that is a question that reveals I don't understand the nitty-gritty of the example that you provided. But if that answer were to be yes (some kind of URL that just gives me my uploaded file iframed, and nothing else in the frame... maybe with the height and width parameters being fed into the URL... yeah, a girl can dream...), that would actually be incredibly good news for me in my efforts to help people use randomizers and other simple javascripts to enhance their content.

THANK YOU again for your help... one of these days I have got to learn to code instead of spending all my time finding content to put in my randomizers! 🙂

Screenshot of the Preview File iframed:

217709_Screen Shot 2017-02-17 at 9.40.35 AM.png

Shar
Community Champion

Howdy laurakgibbs‌,

I'm going to jump into your conversation with  @James  because I believe in the utility of iframe embeds. Smiley Happy

I think you are asking how does someone use a standalone HTML file without hosting it on a private space? How can they just keep the file in their Canvas files section and still embed it? Is this question what you're seeking an answer for?

Using the example script that James showed in an earlier post above, I created a standalone HTML file in Notepad, saved it with .html, and then uploaded it to my files section. Here are my visual examples:

Before Page is saved, embedded script html.

There might be a better way to get the URL, but for me putting the file onto the page, switching to HTML editor, and then grabbing the download code has worked successfully. Sometimes there's also a preview URL, but download works just fine. I learned this technique in this community somewhere.

Usually, I remove the link to the file from the page, but for this example I left it in. Then, here's what happens when I save the page:

After page is saved, html loads.

This alert trigger window is the same behavior that James noted in the earlier post. The HTML file hits the alert first and then only finishes loading after pressing okay.

I've used this technique to insert Polls and other widgets where they give you a <script>....</script> snipet of code to put onto a blog page. hehehe But I just make it a standalone HTML page, and iframe embed it into the Canvas page. Voila! B)

Cheers - Shar

laurakgibbs
Community Champion

OH MY GOSH: ishar-uw‌ that is exactly what I am looking for, and I did not even think of trying the download code. IT WORKED:

Canvas 

(screenshot below)

I will have to play with this some more this weekend to make sure but I think you may have just allowed me to come up with an all-Canvas solution to my widget problems:

widget embedded

Wow, just wow: it works in one of my real pages too, identical to the solution with my external hosting:

download test 2

So, this is just amazing. I will be reworking my widget tutorials this weekend to test and document this all-Canvas solution. stefaniesanders‌ and  @biray ‌ this means I will need another week or two to rework my materials, but this is going to be SO MUCH BETTER now that any Canvas user can apparently run their own https/iframe operation using the Canvas files space.

THANK YOU  @James ‌ and ishar-uw‌, I never would have figured this out on my own. And pinging  @jared ‌ because, hey, this is #connectedlearning at its best. 🙂

James
Community Champion

Thanks ishar-uw‌.

I've been in class all morning and just got around to checking the Community and you saved me the trouble of writing it and you wrote it much more eloquently an authoritatively than I could because you've actually used it.

Even though she originally tagged me, my response to laurakgibbs is simply, "What Shar said."

laurakgibbs
Community Champion

Just to say thanks again, everybody, for helping with this! I tested the Canvas-File-Download with iframe solution for Twitter widgets this morning, and it worked perfectly:

1. I copied the Twitter widget script as supplied by Twitter into a plain text file:

<a class="twitter-timeline" data-height="800" data-dnt="true" href="https://twitter.com/worldlittoday">Tweets by worldlittoday</a> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

2. I uploaded that file, using the html suffix, to a Canvas course file space:

Files 

3. I then used iframe to embed my own Canvas file (using the download link) in a Canvas page:

Sample File Version: Twitter4Canvas 

And it worked perfectly! Screenshot below. I am so glad to have an all-Canvas solution for this method of embedding live content in a Canvas page. There are some advantages for me personally in hosting the scripts externally (so that I can provide copy-and-paste snippets for people who don't even want to go through this file-based process), but for Canvas users who are not afraid of a tiny bit of HTML tinkering, this solution is perfect!

I'll rewrite my Twitter4Canvas workshop materials this weekend based on my new knowledge!!! And thank you, again, to both  @James ‌ and ishar-uw‌ for educating me about iframe security and also for this perfect little trick of using the download link to load content into an iframe. 

Screenshot:

World Lit Today Twitter

Shar
Community Champion

Hi Laura,

I noticed that in your tutorials you advocate using a table to set up the layout for the twitter widget in the right-most column. I'm curious how do these pages display in the mobile app?

I suspect the widget (and everything else in the table) shrinks in size rather than stacking one on top of the other. Have a look at https://community.canvaslms.com/docs/DOC-3289?sr=search&searchId=57a6b0a3-fb43-4de7-a39b-57a6c3554a6...‌ if they are not stacking to learn about DIV tags. 

Good luck,
Cheers - Shar

laurakgibbs
Community Champion

Hi Sharmaine, I teach writing, so mobile is not really part of my world, and in my surveys of students, I know that they do their work for my classes on laptops and desktops because of the extensive writing and editing. A few years ago, there were some students who reported using iPads (and that seemed to work okay; I assume they had keyboards), but even that seems to have died down and now they are back to laptops (I work on a Chromebook myself). But if people are designing for mobile, then tables are definitely less desirable. I don't design for mobile, though, so I don't have a lot of insight into that! I'll link to that page about Canvas Without Tables from my page for people who are seeking a mobile audience.

awilliams
Instructure
Instructure

There is so much awesome in this thread! This is definitely community at it's best. Or a vein of gold to use Josh Coates' instcon 2016‌ analogy.

laurakgibbs
Community Champion

I used the nifty Files-in-Pages trick to make Flickr albums work too! 🙂

Flickr Albums in Canvas Pages – Teaching with Canvas 

Screenshot:

screenshot of Flickr album in Canvas discussion board

teachramos
New Member

Thank you so much all above. Since the OP asked about Remind widgets, that is what brought me to this page as well. Using @laurakgibbs Twitter tutorial, I was able to streamline directions for Remind widget. Thank YOU as this was literally IMPOSSIBLE using everything else I could find on the web. I can't wait to level up my Canvas course, streamline my workflow, and share with colleagues. Y'all are amazing! 😁

Part ONE | How To Create Your Remind Widget

  1. Create your Remind Class
  2. Go to https://www.remind.com/settings/widgets 
  3. Click ADVANCED settings.
  4. Copy the Embed code for Option 3: Wix
  5. On your computer, create a plain text file (Notepad for Windows, TextEdit for Mac)
  6. Paste the embed code from step 4.
  7. Go to File > Save as... > and save as: RemindWidget.html
  8. Upload the file to your course files on Canvas.

Part TWO | Embed Your Widget in a Canvas Page:

  1. Create a new page in your Canvas course.
  2. Click Insert>Embed
    1. Paste the following code: 
      <iframe style="border: 0px #ffffff none;" src="https://canvas.XXXXX.org/courses/00000/files/000000/download" width="29%" height="520px" name="Remind" </iframe></p>

  3. Right click on "Files" in your course navigation and open in a new tab. 
  4. Click to preview your RemindWidget.html file. Look at the address in the address bar.
  5. Change the domain and orange highlighted numbers in the code from step 3 to the ones shown in your address bar. (These represent your course number and the file number).
HeatherMJohnson
New Member

Thank you!! It works! 🙂 

0 Kudos