native Domino links and XPages - url

Users open documents by links in old format http://server/db.nsf/VIEW_UNID/DOC_UNID. The form has property set to open XPage instead.
Origin of these links is email notification generated by "universal agent". It simply sends link to document. It does not know, what form is associated with what XPage, therefore it generates universal links instead of "/page.xsp&documentId=...".
The problem: relative links computed at client do not work - < a href = "/page.xsp?params"> should be more effective - no roundtrip and easy to compute at page load. They evaluate to http://server/db.nsf/0/page.xsp?params, what ends with Error 404, naturaly.
XPage contains "help" section, what is another document with RT field containing text, images and links. And relative links in that RT field work when XPage is opened from another XPage - view (/page.xsp), but fail when redirected from notification link (/0/UNID).
Question: How to effectively reset browser's address bar to extended XPages format http://server/db.nsf/page.xsp?documentId=DOC_UNID after opening redirected documents/views by old fashioned URLs?

Main problem is in discrepancy of relative links on server side (evaluated in SSJS) and client side (evaluated by browser). I have solved my problem by simple redirect in case document is open by old fashioned link.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.script><![CDATA[var url = "#{javascript:context.getUrl()}";
var l = window.location;
if (url != l) {
window.location.replace(url);
}
]]></xp:this.script>
</xp:eventHandler>
</xp:view>
Simply said, if open URL differs from internal URL (as resolved by XSP engine), browser redirects to correct URL. This solved many problems we had with inline images (image resource) and attachments.

Try "./page.xsp&params" or ../ if you want to go back to the root - I have noticed IBM do this in their coding as well. Hope this helps.

Have you tried to set pageBaseUrl property in your XPages? This would help to repair the relativ links:
<xp:this.pageBaseUrl>
<xp:baseUrl>
<xp:this.href><![CDATA[#{javascript:"http://stackoverflow.com/"}]]></xp:this.href>
</xp:baseUrl>
</xp:this.pageBaseUrl>
Another idea is to do a redirect in beforePageLoad-event in the XPage if the URL is in old fashioned style.

Related

Is there a way to x-callback from Telegram to another app?

I am creating a Telegram bot and need to x-callback to another application.
This is my x-callback that opens VLC and streams a video. It works fine when I use it in Siri Shortcuts or in Safari. But I need it to work on Telegram chat conversation.
vlc-x-callback://x-callback-url/stream?url=https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4
When I send it as raw text it obviously doesn't recognize it as a valid url and does nothing.
I have tried to format it Markdown, MarkdownV2 and HTML styles but none works.
I've also tried InlineKeyboardButton giving it the text and url but it throws a BadRequest error
telegram.error.BadRequest: Inline keyboard button url is invalid
Is there any workaround to x-callback from Telegram to another app?
My question is implementation independent, but here is my code using python-telegram-bot
from telegram import Update, ParseMode, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import CommandHandler, CallbackContext, Updater
my_x_callback = 'vlc-x-callback://x-callback-url/stream?url=https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4'
def test(update: Update, context: CallbackContext):
update.message.reply_text(my_x_callback)
update.message.reply_text(f'[Play it on VLC]({my_x_callback})', parse_mode=ParseMode.MARKDOWN)
update.message.reply_text(f'[Play it on VLC]({my_x_callback})', parse_mode=ParseMode.MARKDOWN_V2)
update.message.reply_text(f'Play it on VLC', parse_mode=ParseMode.HTML)
button = InlineKeyboardButton('Play it on VLC', url=my_x_callback)
update.message.reply_text(
'Testing InlineKeyboard',
reply_markup=InlineKeyboardMarkup([[button]])
)
if __name__ == '__main__':
updater = Updater('TOKEN')
updater.dispatcher.add_handler(CommandHandler('test', test))
updater.start_polling()
updater.idle()
I had a similar use case once where I wanted to use mailto: links. My workaround is to create a website URL that points to the mailto: link. I.e. flow is:
Generate mailto link depending on users request
Generate https:// url that points to the link - in my case that's done via a self-hosted YOURLS instance
used that generated URL either for an inline buttton or as text link.

Crystal-lang: How to Find End URL After a Redirect?

I'm just dipping a toe in the water with Crystal at the moment and, as an exercise, trying to port one of my Python scripts across.
The script in question downloads the 'latest' PDF from a URL which takes the form: "http://somesite.com/download/latest/". When visited that URL automatically redirects to the page for the latest download eg. "http://somesite.com/download/4563/"
I'm having difficulty working out how to implement this in Crystal so that I can grab the actual URL that the redirect ends up on.
In Python I do:
currenturl = urllib.request.urlopen(latesturl)
#above will redirect to URL of format http://somesite.com/download/XXXXX/
#where XXXXX is the current d/load
endurl = currenturl.geturl()
...which gives me the end URL in the "endurl" variable.
But, reading the docs for Crystal's "http/client" I can't see any way to return the actual URL that a redirect ends up on. Is it possible?
Crystal's HTTP::Client currently can't automatically follow redirects.
Please note that you're reading an outdated version of the API docs, the current is at https://crystal-lang.org/api/latest/HTTP/Client.html (I don't think there have been relevant changes between 0.24.1 and 0.26.1 though).
But you can easily access the redirect URL from reading the Location header of an HTTP response:
response = HTTP::Client.get latesturl
endurl = response.headers["Location"]

Data URI link <a href="data: doesn't work in Microsoft Edge

This simple code works perfectly everywhere except Microsoft Edge:
link
[JSFiddle]
In Microsoft Edge I'm getting "That's odd...Microsoft can't find this page" error:
Examples from Mozilla documentation also do not working with the same result.
Here's the output from Edge console:
This error occurs when opening a new edge window, on new tabs it inputs data:text/plain;charset=utf-8,Test as search query into the default search engine.
It seems like Microsoft Edge has no definition for data:
Does anyone know a solution to this?
Update: unfortunately, it seems that there's no way to use data URI in links in IE/Edge. I've created related question about detecting data URI support in links: Detect data URI in links support with Modernizr
As of 2020, the new Microsoft Edge built on Chromium supports navigating to data URIs in the address bar like the other Chromium-based browsers. Neither IE nor Microsoft Edge Legacy support this feature; MSDN claims that this is for security reasons.
The only solution for older Microsoft browsers is to link, using a scheme that is supported such as file:// or http://, to some resource that contains the content.
Interestingly enough, the oldest versions of IE (I'm talking older than 6) supported a precursor to data URIs in the about: URI scheme, though only HTML was supported this way. Those URIs no longer work today and simply redirect to "Navigation canceled" (previously "Action canceled") or, in the case of the new Microsoft Edge, are treated as invalid edge:// URIs.
You can try using navigator.msSaveBlob in order to download the data URI in IE/Edge:
var a = document.getElementsByTagName('a')[0];
a.addEventListener('click', function (e) {
if (navigator.msSaveBlob) {
var bytes = atob(a.href.split(',')[1]), array = [];
for(var i = 0; i < bytes.length; i++) array.push(bytes.charCodeAt(i));
navigator.msSaveBlob(new Blob([new Uint8Array(array)], {mime: "text/plain"}), "file.txt");
e.preventDefault();
}
});
Since IE and Edge do support <img> tags with a data URI as the source, you can fudge a link to an image using javascript to write to the document:
<a href="javascript:document.write('<img src=data:image/png;base64,iVBORw0KGgoAA
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC />')">link</a>

How to construct/get Office Web App URL for sharepoint documents

I am trying to get the right redirection URL for my sharepoint documents which then I can use to open documents in WebView of iOS. Currently I am giving the absolute URL for the document where the doc is rendered inside WebView as PDF(Image/Readonly). Whereas I want to redirect to office webapp. Now my issue is I dont know if the URL for office web app is something which I can construct like appending /_layouts/15/WopiFrame.aspx?sourcedoc= or is the URL custom based on installations and we need to call some Sharepoint API which will let us know what is the base URL for Wopi service.
Currently I am passing URL like - https://.sharepoint.com/Shared%20Documents/demo/demo.docx
Whereas I want to pass URL like - https://.sharepoint.com/_layouts/15/WopiFrame.aspx?sourcedoc=/Shared%20Documents/demo/demo.docx
Looking forward for help.
Thanks in advance,
Vishwesh
File f = clientContext.Web.GetFileByServerRelativeUrl("/sites/ /Shared%20Documents/Title.docx");
clientContext.Load(f);
clientContext.ExecuteQuery();
ClientResult<String> result = f.ListItemAllFields.GetWOPIFrameUrl(SPWOPIFrameAction.Edit);
clientContext.Load(f.ListItemAllFields);
clientContext.ExecuteQuery();
result.Value contains a URL, something like this:
http://sharep.xxx:8080/sites/zxxx/_layouts/15/WopiFrame.aspx?sourcedoc=%2Fsites%2Fzxxx%2FShared%20Documents%2FTitle%2Edocx&action=edit
Also you can extract the extract Office Web Apps URL from the above page, if you don't want to hit the sharepoint at all.
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Utilities;
// Assume we have these variables:
// ctx: A valid client context
// serverRelativeUrl: the URL of the document
File f = ctx.Web.GetFileByServerRelativeUrl (serverRelativeUrl);
result = f.ListItemAllFields.GetWOPIFrameUrl(SPWOPIFrameAction.Edit);
ctx.Load(f.ListItemAllFields);
ctx.ExecuteQuery();
This builds on the answer from #thebitlic which was the silver bullet for sure! However he or she is doing two calls to the server. Through the wonders of CSOM batching, it's possible to do it in one round trip, and no need to bring back the File object at all.

Excel links not loading pages, but when the link is pasted in the browser it works.

I have placed hyperlinks in an excel spreadsheet though my ruby-on-rails application. The links are to some privileged pages that require, After the login I am supposed to taken to the requested page. However, what happens is that after login I lang on the home page of the website. Interestingly, when I right-click the link in the excel and paste the link in the web-browser url, it works as expected. So I don't think it's my app's fault, but rather something in excel that I am missing?
My scenario is pretty much the same as this scenario:
http://www.geekstogo.com/forum/topic/289186-excel-2007-hyperlink-loads-web-login-screen-not-linked-urlplease-help-me/
This issue normally happens in IE and i also faced the same problem.
Solution to this is very simple
Create a redirect.html page in your public folder (public folder because you are using ROR)
Copy this to your redirect.html
<html>
<body>
Please wait, loading your page...
<script type="text/javascript">
function getQuerystring(key) {
key = key.replace(/[\[]/,"\\\[").replace(/ [\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
var query = regex.exec(window.location.href);
return query[1];
}
window.location = window.location.protocol + "//" + window.location.host + "/" + getQuerystring('page');
</script>
</body>
</html>
The links you are constructing in excel should be modified
For e.g Old link - http://test.com/post/comments/1
New link should be - http://test.com/redirect.html?page=post/comments/1
You need to pass the part of URL (after base url) as a param
How this works.
When user clicks a link in excel it points to redirect.html and the javascript constructs the actual URL and redirects again to proper page, user will be navigated to actual page if already logged in else redirected to Login/Home page.
Not sure it's really an answer but I had the same problem with my application.
The whole application, including the home page, is protected (I'm using Devise).
So whenever a user wants to access http://myapp, it redirects him to http://myapp/users/sign_in.
I think Devise uses a 301 or a 302 to redirect to the login screens.
My finding is that links clicked in Office and opening in IE cannot accomodate this redirect (no problem when Chrome is the default browser). Does it match your setup?
Ultimately, I have found no other solution but to link directly to the sign-in page... Maybe there are other options but I'm still looking for them.
EDIT: found this article (from 2006) about a bug in Outlook which totally matches our situation.
Again, not a solution, but at least an explanation.
This is a problem with Excel's internal URL handling, which has issues with modern web design patterns (e.g. sessions + redirects).
Here's a client-side solution that bypasses Excel's internal mechanisms and uses the OS default URL handler instead. Note that since it uses macros, this approach requires appropriate security settings.
In your worksheet's VBA module, add the following code:
Option Explicit
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
ByVal hWnd As Long, _
ByVal Operation As String, _
ByVal Filename As String, _
Optional ByVal Parameters As String, _
Optional ByVal Directory As String, _
Optional ByVal WindowStyle As Long = vbMinimizedFocus _
) As Long
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
ShellExecute 0, "Open", Target.Address
End Sub
This is based on the answers of two other SO answers.
I have updated the redirect.html in the answer by #Bharath, replacing the regex manipulation with the Web APIs now available:
URL
URLSearchParams
See the original answer by #Bharath for further explanation.
<!DOCTYPE html>
<html lang="en">
<body>
One moment please. We are trying to connect you ...
<script type="text/javascript">
const url = new URL(window.location.href);
const params = new URLSearchParams(url.search);
const redirectTo = params.get('page');
location = `${url.origin}/${redirectTo}`;
</script>
</body>
</html>
Of course, there is scope to handle errors (e.g. if (params.has('page')) etc.
See also Easy URL Manipulation with URLSearchParams by Eric Bidelman of Google.

Resources