Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prevent not-owned slugs to be open from domain #18

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
/* Step 1: enter your domain name like fruitionsite.com */
const MY_DOMAIN = "fruitionsite.com";

/*
* Step 2: enter your email address registered to Notion.so
* This will be used to match your pages with your Notion account to
* protect other slugs to be open on your custom domain.
*/
const NOTION_MAIL = "me@fruitionsite.com";

/*
* Step 2: enter your URL slug to page ID mapping
* Step 3: enter your URL slug to page ID mapping
* The key on the left is the slug (without the slash)
* The value on the right is the Notion page ID
*/
Expand All @@ -15,15 +22,15 @@ const SLUG_TO_PAGE = {
roadmap: "7d4b21bfb4534364972e8bf9f68c2c36"
};

/* Step 3: enter your page title and description for SEO purposes */
/* Step 4: enter your page title and description for SEO purposes */
const PAGE_TITLE = "Fruition";
const PAGE_DESCRIPTION =
"Free, Open Source Toolkit For Customizing Your Notion Page";

/* Step 4: enter a Google Font name, you can choose from https://fonts.google.com */
/* Step 5: enter a Google Font name, you can choose from https://fonts.google.com */
const GOOGLE_FONT = "Rubik";

/* Step 5: enter any custom scripts you'd like */
/* Step 6: enter any custom scripts you'd like */
const CUSTOM_SCRIPT = ``;

/* CONFIGURATION ENDS HERE */
Expand Down Expand Up @@ -115,7 +122,17 @@ async function fetchAndApply(request) {
},
method: "POST"
});
response = new Response(response.body, response);

let body = await response.text()

// Prevent other users' pages to be loaded
if (url.pathname.includes("loadPageChunk")) {
if (!body.includes(NOTION_MAIL)) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an interesting approach! i like it.

i want to make this more granular though.

loadPageChunk returns several maps: block, space, notion_user, collection_view, and collection. so it's not guaranteed that if the email exists in the response text, the page is created by the user of that email.

but certainly this is on the right track though. i think the correct solution may be (await response.json).recordMap.notion_user.email !== MY_EMAIL. i will look further into this and report back :)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recordMap can have multiple users with different id's (If you duplicate a page template, that's the situation). On a different scenario, I might have a multiple user Notion page and might have no contribution on some of the pages (hence my email won't even exist on those pages). I'll send my solution to this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an interesting approach! i like it.

i want to make this more granular though.

loadPageChunk returns several maps: block, space, notion_user, collection_view, and collection. so it's not guaranteed that if the email exists in the response text, the page is created by the user of that email.

but certainly this is on the right track though. i think the correct solution may be (await response.json).recordMap.notion_user.email !== MY_EMAIL. i will look further into this and report back :)

I thought parsing JSON would cost a bit, so I just checked plaintext. But this can be improved. I'll think on another solution.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit convoluted, but I've been using the code below, where NOTION_EMAILS is an array of emails that can have pages that the custom domain can map to.

const data = JSON.parse(body)
if (!NOTION_EMAILS.includes(data.recordMap.notion_user[Object.keys(data.recordMap.notion_user)[0]].value.email)) {
    throw new Error('page not owned by correct user')
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fyi, as of notion api v3, what I provided no longer works as the recordMap returned by /loadPageChunk no longer contains the notion_user field

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, unfortunately this doesn't work anymore because the space map is no longer in recordMap in the response of loadPageChunk.

would appreciate it if anyone has a better idea in terms of how to fix it.

throw new Error('This page does not belong to this user.')
}
}

response = new Response(body, response);
response.headers.set("Access-Control-Allow-Origin", "*");
} else if (slugs.indexOf(url.pathname.slice(1)) > -1) {
const pageId = SLUG_TO_PAGE[url.pathname.slice(1)];
Expand Down