torchbox / wagtail-grapple

A Wagtail app that makes building GraphQL endpoints a breeze!
https://wagtail-grapple.readthedocs.io/en/latest/
Other
152 stars 57 forks source link

GetPage(id: ..., token: "...") returning null for unpublished pages, breaking headless previews for unpublished pages. #275

Open dopry opened 1 year ago

dopry commented 1 year ago

My headless preview call the GraphQL API to get the page data with the token. When pages are unpublished it is returning null, so that pages cannot be previewed before publishing.

Given

{
  page( id: 367, token: "id=367:1ozhYP:6r6kIgWON9Lag-99mKOs83UioM8T9c2-z93m2cut0W4" ) {
    title
  }
}

When the page is unpublished the response is { "data":{ "page": null }} When the page is published the response is { "data": { "page": { "title": "Test Preview unpublished" }}}

dopry commented 1 year ago

I'm feel like the problem is https://github.com/torchbox/wagtail-grapple/blob/bcf83c88ccbcd1e17e61b1e07babf98604463b7f/grapple/types/pages.py#L181

I feel like live() should not be included if token is set.

zerolab commented 1 year ago

Good 🕵️‍♂️!

dopry commented 1 year ago

@zerolab I'll work on a fix to get_specific_page. I feel like, in a future release, it may be wise to have a separate graphql query for getPagePreview(token: String!). There are a lot of conditions stacking up in get_specific_page, and making .live() and .public() conditional could lead to errors where we accidentally expose draft content to the public.

the token has the page id embedded. So a get_page_preview implementation could potentially be simplified to something like

def get_page_preview(token=None):
   id_str = token.split(':")[0]
   id = id_str.splt("=")  
   page = WagtailPage.objects.get(pk=id).specific()
   if page:
        page_type = type(page)
        if hasattr(page_type, "get_page_from_preview_token"):
            preview = page_type.get_page_from_preview_token(token)
   if preview:
        return preview