Bookmark submission: Fetch page info through back end.
CORS prevents us from fetch the target page directly. This patch
makes the front end use the back end to fetch it instead.
Change-Id: I2d33a68d00b6ce1bb7a7b8dfcb7687f0bd1fdebd
diff --git a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
index 73396d7..a535d0d 100644
--- a/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
+++ b/src/main/java/eu/mulk/mulkcms2/benki/bookmarks/BookmarkResource.java
@@ -1,5 +1,6 @@
package eu.mulk.mulkcms2.benki.bookmarks;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.TEXT_HTML;
import eu.mulk.mulkcms2.benki.accesscontrol.Role;
@@ -11,6 +12,7 @@
import io.quarkus.qute.api.ResourcePath;
import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.SecurityIdentity;
+import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.OffsetDateTime;
@@ -20,6 +22,7 @@
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
+import javax.json.JsonObject;
import javax.json.spi.JsonProvider;
import javax.transaction.Transactional;
import javax.validation.constraints.NotEmpty;
@@ -31,8 +34,10 @@
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import org.jboss.logging.Logger;
+import org.jsoup.Jsoup;
@Path("/bookmarks")
public class BookmarkResource {
@@ -75,9 +80,7 @@
user.id)
.list();
}
- return bookmarkList
- .data("bookmarks", bookmarks)
- .data("authenticated", !identity.isAnonymous());
+ return bookmarkList.data("bookmarks", bookmarks).data("authenticated", !identity.isAnonymous());
}
@POST
@@ -87,7 +90,8 @@
@FormParam("uri") URI uri,
@FormParam("title") @NotEmpty String title,
@FormParam("description") String description,
- @FormParam("visibility") @NotNull @Pattern(regexp = "public|semiprivate|private") String visibility)
+ @FormParam("visibility") @NotNull @Pattern(regexp = "public|semiprivate|private")
+ String visibility)
throws URISyntaxException {
var userName = identity.getPrincipal().getName();
@@ -116,6 +120,15 @@
return Response.seeOther(new URI("/bookmarks")).build();
}
+ @GET
+ @Path("page-info")
+ @Authenticated
+ @Produces(APPLICATION_JSON)
+ public JsonObject getPageInfo(@QueryParam("uri") URI uri) throws IOException {
+ var document = Jsoup.connect(uri.toString()).get();
+ return jsonProvider.createObjectBuilder().add("title", document.title()).build();
+ }
+
@TemplateExtension
static String humanDateTime(TemporalAccessor x) {
return humanDateFormatter.format(x);
diff --git a/src/main/resources/META-INF/resources/bookmarks/bookmarkList.js b/src/main/resources/META-INF/resources/bookmarks/bookmarkList.js
index 11c4b10..4c8287a 100644
--- a/src/main/resources/META-INF/resources/bookmarks/bookmarkList.js
+++ b/src/main/resources/META-INF/resources/bookmarks/bookmarkList.js
@@ -1,5 +1,6 @@
document.addEventListener('DOMContentLoaded', () => {
- let bookmarkSubmissionPane = document.getElementById('bookmark-submission-pane');
+ let bookmarkSubmissionPane = document.getElementById(
+ 'bookmark-submission-pane');
let titleInput = document.getElementById('title-input');
let uriInput = document.getElementById('uri-input');
let uriSpinner = document.getElementById('uri-spinner');
@@ -9,7 +10,10 @@
uriInput.addEventListener('blur', async () => {
uriSpinner.hidden = false;
uriSpinner.playing = true;
- let r = await fetch(uriInput.value);
+ let searchParams = new URLSearchParams({'uri': uriInput.value});
+ console.log(`/bookmarks/page-info?${searchParams}`);
+ let fetchUrl = new URL(`/bookmarks/page-info?${searchParams}`, document.URL);
+ let r = await fetch(fetchUrl);
uriSpinner.hidden = true;
uriSpinner.playing = false;
@@ -17,14 +21,8 @@
return;
}
- let html = await r.text();
- let parser = new DOMParser();
- let doc = parser.parseFromString(html, "text/html");
- let titles = doc.getElementsByTagName('title');
- if (titles.length <= 0) {
- return;
- }
- titleInput.value = titles[0].innerText;
+ let pageInfo = await r.json();
+ titleInput.value = pageInfo.title;
});
});