sign-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev 528326727848
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 1da91c033c738ab74538d13d
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
policy.json
{
  "constants": {
    "AGENT_ADDRESS": "BXLbJJ1sySppwsvgLn7QUA9NwzEoYRDKXTA7SMNWHaXy",
    "AGENT_ADDRESS_BOUND": true
  },
  "auth": {
    "anonymous": true
  },
  "docs/$docId": {
    "description": "A document to sign. Owners prepare and send it; each signer opens it with their own link. Once sent, its content, signers and fields can no longer change. A document is complete when every signer has a signature.",
    "fields": {
      "title": "String",
      "sourceKind": "String!",
      "text": "String",
      "fileHash": "String!",
      "pageCount": "UInt",
      "signers": "String",
      "fields": "String",
      "status": "String",
      "message": "String",
      "createdBy": "String!",
      "createdAt": "UInt!",
      "sentAt": "UInt"
    },
    "rules": {
      "read": "@user.id != null && (get(/docs/$docId/owners/@user.id) != null || get(/docs/$docId/signerjoins/@user.id) != null)",
      "create": "@user.id != null && @newData.createdBy == @user.id && @newData.createdAt <= @time.now && (@newData.status == 'draft' || @newData.status == 'sent') && (@newData.sourceKind == 'pdf' || @newData.sourceKind == 'text') && @StringUtils.length(@newData.title) >= 1 && @StringUtils.length(@newData.title) <= 200 && @StringUtils.length(@newData.text) <= 100000 && @StringUtils.length(@newData.message) <= 2000 && @StringUtils.length(@newData.signers) <= 20000 && @StringUtils.length(@newData.fields) <= 200000 && getAfter(/docs/$docId/owners/@user.id) != null && getAfter(/dockeys/$docId) != null",
      "update": "@user.id != null && get(/docs/$docId/owners/@user.id) != null && @StringUtils.length(@newData.title) >= 1 && @StringUtils.length(@newData.title) <= 200 && @StringUtils.length(@newData.text) <= 100000 && @StringUtils.length(@newData.message) <= 2000 && @StringUtils.length(@newData.signers) <= 20000 && @StringUtils.length(@newData.fields) <= 200000 && (@data.status == 'draft' || (@newData.fields == @data.fields && @newData.signers == @data.signers && @newData.text == @data.text)) && ((@data.status == 'draft' && (@newData.status == 'draft' || @newData.status == 'sent')) || (@data.status == 'sent' && (@newData.status == 'sent' || @newData.status == 'voided')))",
      "delete": "false"
    }
  },
  "docs/$docId/owners/$userId": {
    "description": "Someone who can manage the document: its creator, or anyone who opened its admin link (which carries the admin key).",
    "fields": {
      "at": "UInt!"
    },
    "rules": {
      "read": "@user.id != null && get(/docs/$docId/owners/@user.id) != null",
      "create": "@user.id != null && @user.id == $userId && @newData.at <= @time.now && ((get(/docs/$docId) == null && getAfter(/docs/$docId).createdBy == @user.id) || getAfter(/docclaims/$docId/c/@user.id).key == get(/dockeys/$docId).key)",
      "update": "false",
      "delete": "false"
    }
  },
  "dockeys/$docId": {
    "description": "The document's admin key. Readable by its owners and by the API, which checks keys for assistants.",
    "fields": {
      "key": "String!"
    },
    "rules": {
      "read": "@user.id != null && (@user.id == @const.BOUNDED_PUBLIC_PRINCIPAL_API || get(/docs/$docId/owners/@user.id) != null)",
      "create": "@user.id != null && get(/docs/$docId) == null && getAfter(/docs/$docId).createdBy == @user.id && @StringUtils.length(@newData.key) >= 24",
      "update": "false",
      "delete": "false"
    }
  },
  "docclaims/$docId/c/$userId": {
    "description": "An admin key presented by someone opening the admin link. Never readable.",
    "fields": {
      "key": "String"
    },
    "rules": {
      "read": "false",
      "create": "@user.id != null && @user.id == $userId",
      "update": "@user.id != null && @user.id == $userId",
      "delete": "false"
    }
  },
  "signertokens/$docId/s/$signerId": {
    "description": "The secret in one signer's link. Owners can read it to share the link again.",
    "fields": {
      "token": "String!"
    },
    "rules": {
      "read": "@user.id != null && (@user.id == @const.BOUNDED_PUBLIC_PRINCIPAL_API || get(/docs/$docId/owners/@user.id) != null)",
      "create": "@user.id != null && getAfter(/docs/$docId/owners/@user.id) != null && @StringUtils.length(@newData.token) >= 24",
      "update": "false",
      "delete": "false"
    }
  },
  "signerclaims/$docId/s/$signerId/c/$userId": {
    "description": "A signer token presented by someone opening a signing link. Never readable.",
    "fields": {
      "token": "String"
    },
    "rules": {
      "read": "false",
      "create": "@user.id != null && @user.id == $userId",
      "update": "@user.id != null && @user.id == $userId",
      "delete": "false"
    }
  },
  "docs/$docId/signerjoins/$userId": {
    "description": "A device that opened a signer's link with the right token, and which signer it acts as.",
    "fields": {
      "signerId": "String!",
      "at": "UInt!"
    },
    "rules": {
      "read": "@user.id != null && (@user.id == $userId || get(/docs/$docId/owners/@user.id) != null)",
      "create": "@user.id != null && @user.id == $userId && @newData.at <= @time.now && get(/docs/$docId).status == 'sent' && getAfter(/signerclaims/$docId/s/@newData.signerId/c/@user.id).token == get(/signertokens/$docId/s/@newData.signerId).token",
      "update": "false",
      "delete": "false"
    }
  },
  "docs/$docId/signatures/$signerId": {
    "description": "One signer's completed signature: the values they filled in, their consent, and when. Written once, never changed.",
    "fields": {
      "values": "String!",
      "consent": "Bool!",
      "signedAt": "UInt!",
      "by": "String!",
      "ua": "String!"
    },
    "rules": {
      "read": "@user.id != null && (get(/docs/$docId/owners/@user.id) != null || get(/docs/$docId/signerjoins/@user.id) != null)",
      "create": "@user.id != null && @newData.by == @user.id && @newData.consent == true && @newData.signedAt <= @time.now && get(/docs/$docId/signerjoins/@user.id).signerId == $signerId && get(/docs/$docId).status == 'sent' && @StringUtils.length(@newData.values) <= 600000 && @StringUtils.length(@newData.ua) <= 400",
      "update": "false",
      "delete": "false"
    }
  },
  "docs/$docId/events/$eventId": {
    "description": "The audit trail: created, sent, viewed, signed, voided.",
    "fields": {
      "type": "String!",
      "signerId": "String!",
      "at": "UInt!",
      "by": "String!"
    },
    "rules": {
      "read": "@user.id != null && (get(/docs/$docId/owners/@user.id) != null || get(/docs/$docId/signerjoins/@user.id) != null)",
      "create": "@user.id != null && @newData.by == @user.id && @newData.at <= @time.now && ((getAfter(/docs/$docId/owners/@user.id) != null && (@newData.type == 'created' || @newData.type == 'sent' || @newData.type == 'voided')) || (getAfter(/docs/$docId/signerjoins/@user.id).signerId == @newData.signerId && (@newData.type == 'viewed' || @newData.type == 'signed')))",
      "update": "false",
      "delete": "false"
    }
  },
  "docfiles/$docId/f/$fileId": {
    "type": "storage",
    "description": "The original PDF, uploaded by an owner while the document is a draft. Never replaced.",
    "fields": {
      "owner": "String!"
    },
    "rules": {
      "read": "@user.id != null && (get(/docs/$docId/owners/@user.id) != null || get(/docs/$docId/signerjoins/@user.id) != null)",
      "create": "@user.id != null && @newData.owner == @user.id && get(/docs/$docId/owners/@user.id) != null && get(/docs/$docId).status == 'draft'",
      "update": "false",
      "delete": "false"
    }
  },
  "functions": {
    "api": {
      "auth": "true",
      "entry": "functions/api.ts",
      "public": true,
      "methods": [
        "GET",
        "POST"
      ],
      "cors": "passthrough"
    }
  }
}

Change history

Quality pass: phone signing, edit signers, copy to send again
5283267278 · 5 hours ago
Bounded source sync
15f0fa2e27 · 1 day ago
Bounded source sync
d3aa1ca65b · 1 day ago
Bounded source sync
8e2ca0b773 · 1 day ago
Bounded source sync
5cfa84715c · 1 day ago
Bounded source sync
c849e7b286 · 1 day ago
Bounded source sync
68c1cabe03 · 1 day ago
Bounded source sync
62ae8944f0 · 1 day ago
Bounded source sync
7ed54e7381 · 1 day ago