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.
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 9383f719c9b37ff76411858f
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.
policy.json
{
"auth": {
"anonymous": true
},
"constants": {
"AGENT_ADDRESS": "DZ1EmVTgPmMe69g6vGKPgn3ZvTNtpuHVwLVhEukUCriL",
"AGENT_ADDRESS_BOUND": true
},
"rooms/$roomId": {
"description": "One baby station. Only devices that joined it can read it; the random room id is the secret a pairing code or QR code hands over. session changes every time the station starts, which tells parents to connect again.",
"fields": {
"owner": "String!",
"name": "String",
"session": "String",
"online": "Bool",
"createdAt": "UInt!"
},
"rules": {
"read": "@user.id != null && get(/rooms/$roomId/joins/@user.id) != null",
"create": "@user.id != null && @newData.owner == @user.id && @newData.createdAt <= @time.now && @StringUtils.length(@newData.name) >= 1 && @StringUtils.length(@newData.name) <= 40 && @StringUtils.length(@newData.session) <= 40 && getAfter(/rooms/$roomId/joins/@user.id) != null",
"update": "@user.id != null && @data.owner == @user.id && @StringUtils.length(@newData.name) >= 1 && @StringUtils.length(@newData.name) <= 40 && @StringUtils.length(@newData.session) <= 40",
"delete": "false"
}
},
"rooms/$roomId/joins/$userId": {
"description": "A device paired with the station: the station itself (role baby) or a parent's phone or laptop. Knowing the room id is enough to pair, unless the station removed that device.",
"fields": {
"role": "String!",
"name": "String",
"at": "UInt!"
},
"rules": {
"read": "@user.id != null && get(/rooms/$roomId/joins/@user.id) != null",
"create": "@user.id != null && @user.id == $userId && @newData.at <= @time.now && @StringUtils.length(@newData.name) >= 1 && @StringUtils.length(@newData.name) <= 40 && get(/rooms/$roomId/bans/$userId) == null && ((@newData.role == 'parent' && get(/rooms/$roomId) != null) || (@newData.role == 'baby' && get(/rooms/$roomId) == null && getAfter(/rooms/$roomId).owner == @user.id))",
"update": "@user.id != null && @user.id == $userId && @StringUtils.length(@newData.name) >= 1 && @StringUtils.length(@newData.name) <= 40",
"delete": "@user.id != null && (@user.id == $userId || get(/rooms/$roomId).owner == @user.id)"
}
},
"rooms/$roomId/bans/$userId": {
"description": "A parent device the station removed. It cannot pair with this station again.",
"fields": {
"at": "UInt!"
},
"rules": {
"read": "@user.id != null && (@user.id == $userId || get(/rooms/$roomId).owner == @user.id)",
"create": "@user.id != null && @user.id != $userId && get(/rooms/$roomId).owner == @user.id && @newData.at <= @time.now",
"update": "false",
"delete": "@user.id != null && get(/rooms/$roomId).owner == @user.id"
}
},
"rooms/$roomId/links/$parentId": {
"description": "Connection setup between one parent device and the station (WebRTC signaling): the parent's offer and the station's answer, each a session description that lists the network addresses to try. Video and sound never pass through here; they go device to device. Overwritten on every connection attempt and deleted when the parent forgets the station or is removed.",
"fields": {
"offer": "String",
"offerId": "String",
"session": "String",
"answer": "String",
"answerId": "String",
"at": "UInt"
},
"rules": {
"read": "@user.id != null && (@user.id == $parentId || get(/rooms/$roomId).owner == @user.id) && get(/rooms/$roomId/joins/$parentId) != null",
"create": "@user.id != null && @user.id == $parentId && get(/rooms/$roomId/joins/@user.id) != null && @newData.at <= @time.now && @StringUtils.length(@newData.offer) <= 20000 && @StringUtils.length(@newData.offerId) <= 40 && @StringUtils.length(@newData.session) <= 40 && @newData.answer == '' && @newData.answerId == ''",
"update": "@user.id != null && get(/rooms/$roomId/joins/$parentId) != null && ((@user.id == $parentId && @newData.at <= @time.now && @StringUtils.length(@newData.offer) <= 20000 && @StringUtils.length(@newData.offerId) <= 40 && @StringUtils.length(@newData.session) <= 40 && @newData.answer == '' && @newData.answerId == '') || (get(/rooms/$roomId).owner == @user.id && @newData.offer == @data.offer && @newData.offerId == @data.offerId && @newData.session == @data.session && @newData.at == @data.at && @newData.answerId == @data.offerId && @StringUtils.length(@newData.answer) <= 20000))",
"delete": "@user.id != null && (@user.id == $parentId || get(/rooms/$roomId).owner == @user.id)"
}
},
"codes/$code": {
"description": "A 6-digit pairing code shown on a baby station. It points to the station's room for 10 minutes. Reading one needs a recorded try (codetries), and tries are rate limited, so the million possible codes cannot be scanned. The station deletes its code once a parent pairs or it leaves the pairing screen; an expired code can be taken by another station.",
"fields": {
"room": "String",
"by": "String",
"at": "UInt"
},
"rules": {
"read": "@user.id != null && get(/codetries/@user.id/t/$code) != null && @data.at + 600 >= @time.now",
"create": "@user.id != null && @newData.by == @user.id && @newData.at <= @time.now && @StringUtils.length(@newData.room) == 20",
"update": "@user.id != null && (@data.by == @user.id || @data.at + 600 < @time.now) && @newData.by == @user.id && @newData.at <= @time.now && @StringUtils.length(@newData.room) == 20",
"delete": "@user.id != null && @data.by == @user.id"
}
},
"codetries/$userId/t/$code": {
"description": "One device trying one pairing code. Each device may try 10 codes in 10 minutes, and all devices together 1,000.",
"tier": "durable",
"fields": {
"n": "UInt"
},
"rules": {
"read": "@user.id != null && @user.id == $userId",
"create": "@user.id != null && @user.id == $userId && @newData.n == 1",
"update": "false",
"delete": "false"
},
"invariants": [
{ "type": "rollingSum", "name": "code_tries_per_device", "field": "n", "windowSeconds": 600, "limit": 10, "scopeVariable": "$userId" },
{ "type": "rollingSum", "name": "code_tries_everyone", "field": "n", "windowSeconds": 600, "limit": 1000 }
]
}
}
Change history
Move store links to openapps.free
Release with preview
Bind agent address in policy
Use OpenApps service URLs and add contribution strip (retry)
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync