forms-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 ce303909347f
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 cf614aedcf4cdabfa9c45095
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": "DGB4JCTR1dWu6eoBgKLNQyATFxxB1imgtXGf4rxi2xC9",
    "AGENT_ADDRESS_BOUND": true
  },
  "auth": {
    "anonymous": true
  },
  "defs": {
    "formText": "@StringUtils.length(@newData.title) >= 1 && @StringUtils.length(@newData.title) <= 200 && @StringUtils.length(@newData.description) <= 2000 && @StringUtils.length(@newData.thankYou) <= 1000 && @StringUtils.length(@newData.questions) >= 2 && @StringUtils.length(@newData.questions) <= 100000",
    "isOwner": "@user.id != null && get(/forms/$formId/owners/@user.id) != null"
  },
  "forms/$formId": {
    "description": "A form: its title, questions (a JSON list) and thank-you message. Readable by anyone who opened its link (a join below); only owners can change it.",
    "fields": {
      "title": "String",
      "description": "String",
      "questions": "String",
      "thankYou": "String",
      "closed": "Bool?",
      "createdBy": "String!",
      "createdAt": "UInt!"
    },
    "rules": {
      "read": "@user.id != null && get(/forms/$formId/joins/@user.id) != null",
      "create": "@user.id != null && @newData.createdBy == @user.id && @newData.createdAt <= @time.now && @def.formText && getAfter(/forms/$formId/owners/@user.id) != null && getAfter(/formkeys/$formId) != null",
      "update": "@def.isOwner && @def.formText",
      "delete": "false"
    }
  },
  "forms/$formId/joins/$userId": {
    "description": "Someone who opened the form's link on a device. Knowing the form id is what lets you join, and joining is what lets you read the form.",
    "fields": {
      "at": "UInt!"
    },
    "rules": {
      "read": "@user.id != null && @user.id == $userId",
      "create": "@user.id != null && @user.id == $userId && @newData.at <= @time.now && getAfter(/forms/$formId) != null",
      "update": "false",
      "delete": "false"
    }
  },
  "forms/$formId/owners/$userId": {
    "description": "Someone who can edit the form and read its responses: the creator, or anyone who presented the admin key.",
    "fields": {
      "at": "UInt!"
    },
    "rules": {
      "read": "@user.id != null && get(/forms/$formId/joins/@user.id) != null",
      "create": "@user.id != null && @user.id == $userId && @newData.at <= @time.now && ((get(/forms/$formId) == null && getAfter(/forms/$formId).createdBy == @user.id) || getAfter(/formclaims/$formId/c/@user.id).key == get(/formkeys/$formId).key)",
      "update": "false",
      "delete": "false"
    }
  },
  "formkeys/$formId": {
    "description": "The form's admin key. Only the public API can read it, to check a key someone presents.",
    "fields": {
      "key": "String!"
    },
    "rules": {
      "read": "@user.id == @const.BOUNDED_PUBLIC_PRINCIPAL_API",
      "create": "@user.id != null && get(/forms/$formId) == null && getAfter(/forms/$formId).createdBy == @user.id && @StringUtils.length(@newData.key) == 24",
      "update": "false",
      "delete": "false"
    }
  },
  "formclaims/$formId/c/$userId": {
    "description": "An admin key someone presented to become an owner. Never readable.",
    "fields": {
      "key": "String"
    },
    "rules": {
      "read": "false",
      "create": "@user.id != null && @user.id == $userId",
      "update": "@user.id != null && @user.id == $userId",
      "delete": "false"
    }
  },
  "forms/$formId/responses/$responseId": {
    "description": "One response. answers is a JSON object of question id (or field name) to answer. Anyone who opened the form can add one while it is open; only owners can read or delete them.",
    "fields": {
      "answers": "String!",
      "createdAt": "UInt!",
      "by": "String!"
    },
    "rules": {
      "read": "@def.isOwner",
      "create": "@user.id != null && @newData.by == @user.id && @newData.createdAt <= @time.now && @StringUtils.length(@newData.answers) >= 2 && @StringUtils.length(@newData.answers) <= 120000 && getAfter(/forms/$formId/joins/@user.id) != null && get(/forms/$formId).closed != true",
      "update": "false",
      "delete": "@def.isOwner"
    }
  },
  "functions": {
    "api": {
      "auth": "true",
      "entry": "functions/api.ts",
      "public": true,
      "methods": [
        "GET",
        "POST",
        "PATCH",
        "DELETE"
      ],
      "cors": "passthrough"
    }
  }
}

Change history

Quality pass: conditional questions, 0 to 10 scale, QR code, prefill links, results tabs, API docs
ce30390934 · 4 hours ago
Bounded source sync
7d82add8ae · 1 day ago
Bounded source sync
8230fd7d59 · 1 day ago
Bounded source sync
d92a6e3b44 · 1 day ago
Bounded source sync
b548641922 · 1 day ago
Bounded source sync
b89074ffd2 · 1 day ago