Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0c549ed
fix(oauth): register Google/Apple sign-ins in the connection log (#31)
tranh0anghuan Aug 4, 2026
66cd797
Fix/mail sender identity (#32)
tranh0anghuan Aug 4, 2026
2df9472
Fix/onboarding flow reliability (#33)
tranh0anghuan Aug 5, 2026
030ab95
feat(onboarding): push the referral row when onboarding completes (#34)
tranh0anghuan Aug 7, 2026
1b97c9b
ci: deploy PROD from main branch [skip ci]
tobao17 Aug 9, 2026
5fc435a
fix(email): send transactional mail as multipart/alternative
Aug 11, 2026
b0d5ac7
Fix/apple callback error handling (#36)
tranh0anghuan Aug 12, 2026
eb38691
feat(oauth): report the Google Ads sign-up conversion for new SSO acc…
tobao17 Aug 12, 2026
e4f0dff
fix(onboarding): let save_onboarding_intent clear a stored goal (#37)
tranh0anghuan Aug 17, 2026
66fa8ac
Feat/onboarding persist invites (#38)
tranh0anghuan Aug 17, 2026
0fd5724
Feat/utm content (#39)
tranh0anghuan Aug 24, 2026
054ddf3
fix: force English profile language on account creation
tobao17 Aug 24, 2026
6ae8d73
Merge fix/force-english-signup into test
tobao17 Aug 24, 2026
8f331ae
fix: force English profile language on account creation
tobao17 Aug 24, 2026
b0655b2
Merge cp/fe-preview into preview
tobao17 Aug 24, 2026
a931ca9
feat(funnel): report the onboarded activation milestone (#40)
tranh0anghuan Aug 25, 2026
b40ff35
Feat/promo tracking send email (#43)
tranh0anghuan Aug 28, 2026
8d09eae
feat(oauth): hand mobile sign-ins to the app through a one-time claim…
aaron-tsar Sep 2, 2026
100d657
feat(apple): native Sign in with Apple for the mobile app
aaron-tsar Sep 2, 2026
a06c7e4
feat(signup): stop seeding Internal and External workspaces
luongtrieuvy202 Sep 5, 2026
fe983cc
ci: pin deploy job to the stage runner [skip ci]
tobao17 Sep 7, 2026
ad051fa
ci: pin deploy job to the stage runner [skip ci]
tobao17 Sep 7, 2026
337a5ad
chore: merge preview into test (keep test apple.js callback)
tobao17 Sep 8, 2026
0231241
Merge pull request #44 from drumee/test
tobao17 Sep 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ permissions:
jobs:
deploy:
name: Deploy
runs-on: self-hosted
runs-on: [self-hosted, drumee-in]
timeout-minutes: 15
env:
SGP_USER: debian
Expand Down
16 changes: 16 additions & 0 deletions acl/apple.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@
"src": "anonymous",
"fast_check": "public-api"
}
},
"native_nonce": {
"doc": "Mint the nonce a native (iOS) Sign in with Apple request must carry; bound to the calling session, single use.",
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"native_signin": {
"doc": "Verify a native (iOS) Apple identity token against this deployment's bundle id and sign the calling session in.",
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
}
},
"modules": {
Expand Down
8 changes: 8 additions & 0 deletions acl/oauth.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
{
"services": {
"claim": {
"doc": "Redeem the one-time hand-off code a mobile OAuth callback issued; signs in the calling session when it is the one that started the flow.",
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"verify_otp": {
"doc": "Verify the 2FA OTP for a pending OAuth sign-in and finalize the session.",
"scope": "hub",
Expand Down
70 changes: 49 additions & 21 deletions acl/onboarding.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,145 +5,173 @@
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_signup_info": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Pre-auth signup step: by definition there is no user yet."
},
"save_usage_plan": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_industry": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_role": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_team_size": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_intent": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_challenges": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_invites": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_tools": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"save_privacy": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"get_response": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"check_completion": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"mark_complete": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"get_countries": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Static reference list used by the signup country picker."
},
"reset": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"update_profile": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"get_env": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Static client config (db_name / xlink). No user data."
},
"get_onboarding_invite_link": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"send_onboarding_invites": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
},
"log": true
"log": true,
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
},
"get_activation_status": {
"scope": "hub",
"permission": {
"src": "anonymous",
"fast_check": "public-api"
}
},
"doc": "Reachability only - authentication is enforced in service/onboarding.js by _identity(), which rejects anonymous callers (ID_NOBODY) with 401 and keys every row on the caller's uid. Do NOT set src:owner here: onboarding requests carry no hub_id, so the ACL resolves them against the endpoint's own hub, and a user in onboarding never owns that hub - it denies every call with PERMISSION_DENIED. (contact.invite can use src:owner only because it passes hub_id: Visitor.id, i.e. the caller's own hub.)"
}
},
"modules": {
"private": "service/onboarding",
"public": "service/onboarding"
}
}
}
Loading
Loading