Spreadsheet Sharing

Users can share spreadsheets via links or embed them on websites. Access control is implemented by the developer, with rules based on ownership, privacy, invitation status or other criteria.

Sharing via Link

When a user opens a spreadsheet link, your authentication logic can verify ownership or a valid invitation. Public spreadsheets open directly; private ones through invitation links.

Inviting a New User

Jspreadsheet Server includes an interface for generating invitations. Adding a user creates a unique invitation token, managed through the interface or the API, if enabled.

Invitation Token

The invitation token is a hash appended to the spreadsheet URL, which the server validates against your access rules. See authentication methods.

Example: https://yourdomain.com/sheets/4b8bd2c1-f3c4-4c36-b4ec-e5e3fb15f1e7/27aff468

On the REST API the invitation code travels as a suffix of the Bearer token (Authorization: Bearer <token>,<invitation>); the server splits it off and exposes it to your authorization hooks as auth.invitation, alongside auth.token.

Token Persistence

The invitation is typically stored in the document, as the hash of an entry in the users array:

{
    spreadsheet: {},
    users: [
        {
            email: 'test@test.com',
            level: 0, // 0 = read-only, 1 = editor, 2 = owner
            hash: '27aff468'
        }
    ]
}

Your access-control code matches a request's invitation code against users[].hash and grants that entry's level: 0 (read-only), 1 (editor) or 2 (owner). The full lookup is in authentication.

Managing Invited Users

The intrasheets extension registers owner-only REST routes to manage the invited users of a document:

  • GET /api/<guid>/users: list the invited users.
  • POST /api/<guid>/users: add or update invited users. The body carries a data field with a JSON-encoded array of user objects; every entry must include an email. Submitted users are merged with the current list, de-duplicated by email.
  • DELETE /api/<guid>/users/<email>: remove the invited user with that email.

All three routes are gated by the server's isOwner hook, and the resulting setUsers operation is persisted through the user store you configure with intrasheets({ users: { get, set } }).

Public and Private Spreadsheets

Each document carries a privacy flag, set through POST /api/<guid>/privacy with a privacy field (1 or true for private, anything else for public). The route applies a setConfig change, an owner-only method in the reference wiring. In the reference access-control logic, a document with privacy unset grants editor access to any authenticated user; a private one requires ownership or a valid invitation.

Custom Email Notifications

Persisting invited users is up to you, through the intrasheets extension's users option. Its set callback is the place to trigger invitation emails:

// Configure the intrasheets extension's user management (invited users per spreadsheet)
intrasheets({
    users: {
        get: async function(guid, auth) {
            // Only the owner can list invited users
            let level = await getUserLevel(guid, auth);
            if (level === 2) {
                return await adapter.getUsers(guid);
            }
        },
        set: async function(guid, data, newUsers, auth) {
            // Only the owner can change invited users
            let level = await getUserLevel(guid, auth);
            if (level === 2) {
                // New users might need to receive an invitation by email. Add that here
                return await adapter.setUsers(guid, data);
            }
        },
    },
});

The set callback receives four arguments: the document guid, the full merged users array to persist, the newUsers submitted in the current request (or null on removal), and the auth object of the caller.

Embed Spreadsheets

For public spreadsheets, the Jspreadsheet Server application generates embed snippets for websites.

Formifier

Sample Code

A generated snippet:

<div id="spreadsheet"></div>
<script src="https://cdn.jsdelivr.net/npm/@jspreadsheet/cloudify/dist/index.min.js"></script>
<script>
// Create a Jspreadsheet Cloud spreadsheet
cloudify(document.getElementById('spreadsheet'), {
    url: 'https://yourdomain.com/api',
    guid: '1766f0e3-f898-47d8-8e34-f8efaee471ff',
    license: 'your-license',
});
</script>