Skip to content

Initial pass at adding clerk login flow to tina#577

Open
ajolipa wants to merge 38 commits intodevelopfrom
RB-clerk-auth
Open

Initial pass at adding clerk login flow to tina#577
ajolipa wants to merge 38 commits intodevelopfrom
RB-clerk-auth

Conversation

@ajolipa
Copy link
Copy Markdown
Contributor

@ajolipa ajolipa commented Mar 18, 2026

In this PR

Migrates SSO from Keycloak to Clerk.
image

Notes and limitations

  • To make the Clerk integration work smoothly, TinaCMS was updated to the latest version (3.6.1), along with some of its related packages. The Keycloak integration no longer works as previously configured in the older version, so is removed entirely in this PR. If we wanted to support both Keycloak and Clerk simultaneously (which I don't think we do), more work would have to be done to figure out how to make that possible.
  • Ideally we would hide or disable any fields that the current user is not allowed to alter, but that would involve creating custom components for each of them that work along the same model as the current PublishToggle component. Certainly possible, but a lot of busywork (maybe this is where Claude could actually step up and help?).
  • If a non-admin user attempts to delete or rename a post from the list of all posts, the whole page crashes, due to some sort of bug on Tina's end about how the error handling is done. If you reload the page everything's fine and the document was not deleted/renamed.

How to test

  • Go to https://padp.staging.performant.studio/admin/ and attempt to log in with an account that's a member of the Performant Software organization within the Performant Studio Staging application. You should receive an email code (or enter your password, depending on the user settings in Clerk I believe) and successfully log in to Tina. Once logged in you should see the PADP staging homepage and the Tina sidebar on the left.
  • Click on the hamburger menu in the top left and go to the Posts collection. You should be able to create a new post. When you create your post, you should not be able to edit the Published field. (You should just see the word "Unpublished" and not be able to interact with it.) The post should publish successfully and redirect you once saved to the visual editor view.
  • You should now see your own email as the creator, and be able to edit any field except for the creator and published fields, using the visual editor. You should be able to save your edits.
image
  • If you attempt to do anything other than edit your own post, you should receive some sort of error message. (Note: this is the main thing I would like to improve if there's any further time -- the error messages currently are not helpful to the user, and in some cases put the site in a temporarily broken state (fixed by refreshing).) This includes editing other people's posts, attempting to delete or rename a post, or trying to access any of the collections other than Posts and Paths.
  • Log out using the button at the bottom of the sidebar menu.
image
  • Log in again, this time with a user with the admin role in the organization. You should now be able to do anything you want, including editing other collections, deleting posts, and toggling the Published state of posts. (Note even admins cannot currently edit the Creator field of a post.) Go ahead and publish the post that your student account made.
  • Log out and back in as the student. Now that your post was published, you should no longer be able to make edits to it.
  • All of the above should also work for the Paths collection.
  • Log out and attempt to log in as a user who is not part of the correct organization. You should not be authenticated.

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for juel-staging failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/juel-staging/deploys/69c6ce0bca70af0008720e70

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for pss-scavenger-hunt failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/pss-scavenger-hunt/deploys/69c6ce0ad64d420007399e4f

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for padp-staging ready!

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/padp-staging/deploys/69c6ce0a93e9bb0009324cef
😎 Deploy Preview https://deploy-preview-577--padp-staging.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for juel-ancestry failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/juel-ancestry/deploys/69c6ce0a80f14a000811e1c9

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for gbof-c19nyc-staging failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/gbof-c19nyc-staging/deploys/69c6ce0a65b8c60008be8f55

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for registro-project failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/registro-project/deploys/69c6ce0a99eff20007e3ccb4

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for universities-studying-slavery failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/universities-studying-slavery/deploys/69c6ce0a0ba0fd000824f422

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for juel-life failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/juel-life/deploys/69c6ce0a11d8d90008d9dad4

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for libertos failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/libertos/deploys/69c6ce0af2cbda0008689378

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 18, 2026

Deploy Preview for gamepossible failed. Why did it fail? →

Name Link
🔨 Latest commit 8540b3a
🔍 Latest deploy log https://app.netlify.com/projects/gamepossible/deploys/69c6ce0abdc48800086840b5

@ajolipa ajolipa marked this pull request as ready for review March 20, 2026 14:52
@camdendotlol
Copy link
Copy Markdown
Contributor

Does this make Tina entirely dependent on Clerk, or is there still a way to set up local authentication?

@ajolipa
Copy link
Copy Markdown
Contributor Author

ajolipa commented Mar 20, 2026

Does this make Tina entirely dependent on Clerk, or is there still a way to set up local authentication?

It just replaces Keycloak. The native Tina user management is still possible (and is the default unless you set a certain env variable to true).

Expanding on this -- one thing that hasn't been done yet but could/should be is to implement the role-based permissions stuff for the default user management. Right now it's all tied to the way Clerk does organizations and roles, but in principle there's no reason we can't also have a role field on users in the Tina user collection and use it for some of these same permissions, although it might be somewhat involved to implement because right now we're using the backend auth provider just out-of-the-box, and we'd presumably have to make a custom version that takes the role field into consideration. I don't think it's unreasonable for now to basically just say that if all you need is a simple users list that's unique to the Tina project then you can use the native user management, and if you want all the bells and whistles of Performant Studio SSO and role management you can use Clerk. But it's something to think about in the future at least.

@jamiefolsom
Copy link
Copy Markdown
Member

A few testing notes:

  • I logged in with my PSS email, which I believe is an admin account, and created a test post but did not check "published"; yet when I visit https://padp.staging.performant.studio/en/posts/ in an incognito window, I do see that test post live on the site. Should have to check "published" to see it.
  • Likewise, I've logged in as a Member, and while I am correctly prevented from editing another user's existing post, and from toggling the published field, when I go to https://padp.staging.performant.studio/en/posts/Member-Test-Post/ in a browser where I'm not logged in at all, I do see the member test post, when I should not, since it's supposedly not published.

ajolipa and others added 3 commits March 20, 2026 15:53
session.remove() ends the current session token but leaves Clerk's
browser-level sign-in state intact via cookies. signOut() clears
both, ensuring a full logout. In practice the current code works
because Clerk's UI re-prompts on the next page load, but signOut()
is the documented way to fully end a Clerk session.
In SSR mode, any post/path slug is handled dynamically regardless of
getStaticPaths. Unpublished content was accessible by direct URL.
Now the page routes check published status before rendering.
@jamiefolsom jamiefolsom mentioned this pull request Mar 23, 2026
7 tasks
@jamiefolsom jamiefolsom mentioned this pull request Mar 23, 2026
5 tasks
jamiefolsom and others added 3 commits March 23, 2026 22:05
- Shared getUserRole helper with dev-mode override for local testing
- MutationObserver locks admin-only sidebar links (Settings, Branding,
  Internationalization, Navbar) with gray styling and lock icon
- Ownership notice banner on posts/paths when viewing another user's
  content
- beforeSubmit guard blocks saves for non-owners with clear error
- Refactor PublishToggle to use shared role detection
- CSS-disable all form fields (inputs, buttons, date picker, dropzone)
- Hide status dot SVG, show lock icon in form header
- Fix banner text and sizing (remove email, fix overflow)
- Use useEffect for data attribute to avoid render loops
- Add Pages to admin-only sidebar collections
- Consolidate CSS selectors to target form scroll area
- cmsCallback only loads role-ui when TINA_PUBLIC_AUTH_USE_SSO is true
- getUserRole defaults to admin when no Clerk user is found
- Non-Clerk sites are unaffected by RBAC restrictions
@jamiefolsom jamiefolsom mentioned this pull request Mar 31, 2026
11 tasks
Copy link
Copy Markdown
Member

@jamiefolsom jamiefolsom left a comment

Choose a reason for hiding this comment

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

Staging is working for me as described. There is a short list of other issues to be addressed, but that need not block merging this PR. #602

// Copy the "content" folder to the current directory
fs.cpSync(`${TEMP_DIR}/content`, './content', { recursive: true });

// Append any custom Netlify config to the main one
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See #594 -- both frames of the Tina Visual Editor have to be served from the same origin, likely the *.performant.studio subdomain, or else we get a cross origin security error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants