TinyMCE AI with JWT authentication (Node.js) Guide

Introduction

TinyMCE AI requires setting up JSON Web Token (JWT) authentication to maintain control over AI feature access. A JWT endpoint generates and provides authorization tokens that verify users are authorized to use AI features, preventing unauthorized access. As a standard web services authorization solution, JWT is documented extensively at https://jwt.io/.

This guide provides a comprehensive walkthrough for integrating TinyMCE AI with TinyMCE, including TinyMCE AI functionality, by using a Node.js server for JWT token generation. It covers project setup, server configuration, and TinyMCE customization.

What You’ll Build

Before diving into the technical details, here’s what you’ll achieve with this guide:

  • A working TinyMCE editor running the TinyMCE AI plugin

  • A secure authentication system using JWT tokens

  • A simple Node.js server to handle the authentication

This guide is designed for developers new to JWT authentication and TinyMCE integration.

Prerequisites

Before starting, ensure you have:

  • Node.js installed on your computer (to check, run node -v in your terminal)

  • A TinyMCE API key with TinyMCE AI enabled (get one from TinyMCE’s website)

  • Basic familiarity with the command line

Make sure you have your API key ready before starting. You’ll need it for both the server and client configuration.

Quick Start Guide

Project Setup

# Create and enter project directory
mkdir tinymce-my-app
cd tinymce-my-app

# Initialize project
npm init -y

# Install required packages
npm install express cors jsonwebtoken

Verify that the package.json file now includes the required dependencies.

Create Project Structure

# Create the public folder for your web files
mkdir public
touch public/index.html
touch jwt.js

Your project should look like this:

/tinymce-my-app
  /public
    index.html  (TinyMCE webpage)
  jwt.js        (Server code)
  package.json  (Project configuration)

Setup

Generate a Public/Private Key Pair

Setting up JWT authentication

To set up JSON Web Token (JWT) authentication for TinyMCE TinyMCE AI:

  1. Add a public key to your Tiny Account, login.

  2. Set up a JSON Web Token (JWT) Provider endpoint via Tiny Account - JWT Keys

  3. Configure your TinyMCE to use the JWT endpoint.

The TinyMCE AI Server requires a public key generated from the same private key that will be used on your JSON Web Token (JWT) provider endpoint. The public key(s) stored on the TinyMCE AI Server are used to ensure that content is sent by authorized users.

There are two methods for generating and adding a public key in the JWT Keys section of your account portal:

  1. Generate New Keypair at Tiny Account - JWT Keys (recommended).

  2. Generate a key pair locally and Import Public Key at Tiny Account - JWT Keys.

Generate a key pair using the Tiny Account JWT Keys page

The Tiny Account - JWT Keys page provides a "Generate New Keypair" option, providing a quick and secure way of generating the required keys. This will store a copy of the public key, and provide a downloadable file for both the public and private keys. Tiny does not store the private key and the key pair cannot be retrieved later.

Generate a key pair locally

When generating a key pair locally, use one of the supported algorithms. TinyMCE AI does not support symmetrical encryption algorithms, such as HS256. Tiny recommends using the RS256 algorithm. The following algorithms are supported:

  • RS256

  • RS384

  • RS512

  • PS256

  • PS384

  • PS512

For instructions on generating a key pair locally, see: Creating a private/public key pair for Tiny Cloud.

Add a public key in the JWT Keys section of your account portal

Once a public key has been generated locally, use the "Import Public Key" option in the JWT Keys section of your account portal at: Tiny Account - JWT Keys.

Set up a JSON Web Token (JWT) endpoint

A JSON Web Token (JWT) endpoint is a service for generating and providing authorization tokens to users. These tokens can then be used to verify that submitted content was sent by an authorized user and to prevent unauthorized access.

The following diagram shows how JWTs are used:

JSON Web Token Call Flow
Figure 1. JSON Web Token Call Flow

When a user opens TinyMCE AI:

JWT endpoint requirements

A JSON Web Token (JWT) endpoint for TinyMCE AI requires:

  • The endpoint or server accepts a JSON HTTP POST request.

  • User authentication - A method of verifying the user, and that they should have access to the TinyMCE AI.

  • The JWTs are generated (signed) using the private key that pairs with the public key provided to Tiny Account - JWT Keys.

  • The endpoint or server produces a plain text response with the token. TinyMCE AI will submit the token with requests to the AI service.

Unlike some other TinyMCE plugins, TinyMCE AI expects the token as a plain text string, not a JSON object. Make sure your endpoint returns the token directly as text.

Required JWT claims for TinyMCE AI

JSON Web Tokens produced by the JWT endpoint must include the following claims:

aud (required)

Type: String

The aud is a case-sensitive string that must match a valid API key that has the TinyMCE AI plugin enabled.

sub (required)

Type: String

The sub claim identifies the user. This should be a unique identifier for the user making the request.

iat (required)

Type: Number

The iat represents the issue timestamp, specified as the number of seconds. For example, to set the issue time to the current timestamp, calculate the issue time as the current timestamp divided by 1000.

Example
iat: Math.floor(Date.now() / 1000), // Issue timestamp
exp (required)

Type: Number

The exp represents the expiration timestamp, specified as the number of seconds. For example, to set a validity period of 10 minutes, calculate the expiration time as the current timestamp plus 600 seconds.

Example
exp: Math.floor(Date.now() / 1000) + (60 * 10) // Expiration time (10 minutes)
auth (required)

Type: Object

The auth object contains AI-specific permissions that control which features the user can access.

Example
auth: {
  ai: {
    permissions: [
      "ai:conversations:read",
      "ai:conversations:write",
      "ai:models:agent",
      "ai:actions:system:*",
      "ai:reviews:system:*"
    ]
  }
}

See Permissions for a complete list of available permissions and best practices for configuring user access.

Server Setup (jwt.js)

In the root directory, copy and paste the server setup code into the jwt.js file.

const express = require('express'); // Sets up the web server.
const jwt = require('jsonwebtoken'); // Generates and signs JWTs.
const cors = require('cors'); // Allows cross-origin requests.
const path = require('path'); // Handles file paths.

const app = express();
app.use(cors());

// Your private key (Replace this with your actual key)
const privateKey = `
-----BEGIN PRIVATE KEY-----
{Your private PKCS8 key goes here}
-----END PRIVATE KEY-----
`;

app.use(express.static(path.join(__dirname, 'public')));

// JWT token generation endpoint
app.post('/jwt', (req, res) => {
    const payload = {
        aud: 'no-api-key', // Replace with your actual API key
        sub: 'user-id', // Replace with actual user identifier
        iat: Math.floor(Date.now() / 1000), // Issue timestamp
        exp: Math.floor(Date.now() / 1000) + (60 * 10), // Expiration time (10 minutes)
        auth: {
            ai: {
                permissions: [
                    'ai:conversations:read',
                    'ai:conversations:write',
                    'ai:models:agent',
                    'ai:actions:system:*',
                    'ai:reviews:system:*'
                ]
            }
        }
    };

    try {
        // Tokens are signed with the RS256 algorithm using your private key
        const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });
        // TinyMCE AI expects the token as a plain string, not JSON
        res.send(token);
    } catch (error) {
        res.status(500).send('Failed to generate JWT token.');
        console.error(error.message);
    }
});

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}`);
});

The JWT payload includes an auth.ai.permissions array that defines what AI features the user can access. Adjust these permissions based on your requirements. See Permissions for more details on available permissions.

Web Page (public/index.html)

Inside the public folder where you created the index.html file add the HTML setup code.

<!DOCTYPE html>
<html>
<head>
  <title>TinyMCE with TinyMCE AI</title>
  <script
    src="https://cdn.tiny.cloud/1/no-api-key/tinymce/8/tinymce.min.js"
    referrerpolicy="origin"
    crossorigin="anonymous">
  </script>
  <script>
    tinymce.init({
      selector: 'textarea',
      plugins: 'tinymceai',
      toolbar: 'showai aiquickactions aireview',
      // tinymceai_token_provider fetches a token from the `/jwt` endpoint.
      // TinyMCE AI expects the response to be a plain text token string.
      tinymceai_token_provider: () => {
        return fetch('http://localhost:3000/jwt', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
        }).then(response => response.text());
      },
    });
  </script>
</head>
<body>
  <h1>TinyMCE AI Demo</h1>
  <textarea>
    Welcome to TinyMCE! Try the AI features like chat, quick actions, and review.
  </textarea>
</body>
</html>

Configuration Steps

Add Your API Key

  • Replace no-api-key in both files with your actual TinyMCE API key

  • The API key should be the same in both the HTML script source and the JWT payload

Add Your Private Key

  • Replace the private key placeholder in jwt.js with your actual private key

  • Make sure it’s in PKCS8 format

  • Keep this key secure and never share it publicly

Configure AI Permissions

  • Adjust the auth.ai.permissions array in the JWT payload based on your requirements

  • See Permissions for available permissions and best practices

Running Your Project

  1. Start the server:

    node jwt.js
  2. Open your browser to: http://localhost:3000

  3. You should see:

    • The TinyMCE editor

    • AI feature buttons in the toolbar (showai, aiquickactions, aireview)

When you run the project, you should see:

  • The TinyMCE editor

  • AI feature buttons in the toolbar (showai, aiquickactions, aireview)