@bongos/core 1.19.791 → 1.19.792
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bongos-core.json +43 -28
- package/.claude/skills/builder-reauth/SKILL.md +5 -3
- package/README.md +1 -1
- package/docs/adr/0206-own-scoped-session-revocation-no-absolute-ceiling.md +2 -0
- package/docs/adr/0294-cli-sessions-do-not-expire.md +56 -0
- package/docs/adr/README.md +1 -0
- package/docs/copy-inventory.md +31 -31
- package/docs/copy-registry.json +41 -41
- package/docs/module-api-changelog.md +2 -0
- package/migrations/core_243_cli_sessions_never_expire.sql +58 -0
- package/modules/hall-ui/public/settings.js +5 -2
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/box-auth-check.js +1 -1
- package/scripts/gds/cli-lib.js +2 -2
- package/scripts/gds/reauth.js +9 -7
- package/scripts/gds/run-unit-tests.js +7 -0
- package/src/bongos/auth-github.js +2 -0
- package/src/bongos/db-kernel.js +29 -11
- package/src/bongos/db.js +33 -24
- package/src/bongos/routes/auth.js +3 -2
- package/src/module-api.js +1 -1
- package/tests/auth_session_expiry_db.mjs +183 -0
- package/tests/auth_session_ttl.mjs +124 -11
package/docs/copy-registry.json
CHANGED
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"modules/hall-ui/public/settings.js:615",
|
|
69
69
|
"modules/hall-ui/public/settings.js:714",
|
|
70
70
|
"modules/hall-ui/public/settings.js:794",
|
|
71
|
-
"modules/hall-ui/public/settings.js:
|
|
71
|
+
"modules/hall-ui/public/settings.js:1096"
|
|
72
72
|
]
|
|
73
73
|
},
|
|
74
74
|
{
|
|
@@ -1520,7 +1520,7 @@
|
|
|
1520
1520
|
"occurrences": 2,
|
|
1521
1521
|
"at": [
|
|
1522
1522
|
"modules/hall-ui/public/settings.js:788",
|
|
1523
|
-
"modules/hall-ui/public/settings.js:
|
|
1523
|
+
"modules/hall-ui/public/settings.js:1349"
|
|
1524
1524
|
]
|
|
1525
1525
|
},
|
|
1526
1526
|
{
|
|
@@ -3097,7 +3097,7 @@
|
|
|
3097
3097
|
"surface": "builders-hall",
|
|
3098
3098
|
"text": "Checking your key…",
|
|
3099
3099
|
"file": "modules/hall-ui/public/settings.js",
|
|
3100
|
-
"line":
|
|
3100
|
+
"line": 1073,
|
|
3101
3101
|
"origin": "js-text-assign",
|
|
3102
3102
|
"confidence": "certain"
|
|
3103
3103
|
},
|
|
@@ -3691,7 +3691,7 @@
|
|
|
3691
3691
|
"surface": "builders-hall",
|
|
3692
3692
|
"text": "Could not copy automatically — select and copy manually. ({…})",
|
|
3693
3693
|
"file": "modules/hall-ui/public/settings.js",
|
|
3694
|
-
"line":
|
|
3694
|
+
"line": 952,
|
|
3695
3695
|
"origin": "js-notice",
|
|
3696
3696
|
"confidence": "certain"
|
|
3697
3697
|
},
|
|
@@ -3889,7 +3889,7 @@
|
|
|
3889
3889
|
"surface": "builders-hall",
|
|
3890
3890
|
"text": "Could not load your account. Reload the page to try again.",
|
|
3891
3891
|
"file": "modules/hall-ui/public/settings.js",
|
|
3892
|
-
"line":
|
|
3892
|
+
"line": 1332,
|
|
3893
3893
|
"origin": "js-text-assign",
|
|
3894
3894
|
"confidence": "certain"
|
|
3895
3895
|
},
|
|
@@ -3916,7 +3916,7 @@
|
|
|
3916
3916
|
"surface": "builders-hall",
|
|
3917
3917
|
"text": "Could not load your settings.",
|
|
3918
3918
|
"file": "modules/hall-ui/public/settings.js",
|
|
3919
|
-
"line":
|
|
3919
|
+
"line": 1335,
|
|
3920
3920
|
"origin": "js-notice",
|
|
3921
3921
|
"confidence": "certain"
|
|
3922
3922
|
},
|
|
@@ -3961,7 +3961,7 @@
|
|
|
3961
3961
|
"surface": "builders-hall",
|
|
3962
3962
|
"text": "Could not remove your key. Try again.",
|
|
3963
3963
|
"file": "modules/hall-ui/public/settings.js",
|
|
3964
|
-
"line":
|
|
3964
|
+
"line": 1153,
|
|
3965
3965
|
"origin": "js-notice",
|
|
3966
3966
|
"confidence": "certain"
|
|
3967
3967
|
},
|
|
@@ -3970,7 +3970,7 @@
|
|
|
3970
3970
|
"surface": "builders-hall",
|
|
3971
3971
|
"text": "Could not remove. Try again.",
|
|
3972
3972
|
"file": "modules/hall-ui/public/settings.js",
|
|
3973
|
-
"line":
|
|
3973
|
+
"line": 1152,
|
|
3974
3974
|
"origin": "js-text-assign",
|
|
3975
3975
|
"confidence": "certain"
|
|
3976
3976
|
},
|
|
@@ -4033,7 +4033,7 @@
|
|
|
4033
4033
|
"surface": "builders-hall",
|
|
4034
4034
|
"text": "Could not save your key. Try again.",
|
|
4035
4035
|
"file": "modules/hall-ui/public/settings.js",
|
|
4036
|
-
"line":
|
|
4036
|
+
"line": 1097,
|
|
4037
4037
|
"origin": "js-notice",
|
|
4038
4038
|
"confidence": "certain"
|
|
4039
4039
|
},
|
|
@@ -4177,7 +4177,7 @@
|
|
|
4177
4177
|
"surface": "builders-hall",
|
|
4178
4178
|
"text": "Could not save. Try again.",
|
|
4179
4179
|
"file": "modules/hall-ui/public/settings.js",
|
|
4180
|
-
"line":
|
|
4180
|
+
"line": 1096,
|
|
4181
4181
|
"origin": "js-text-assign",
|
|
4182
4182
|
"confidence": "certain"
|
|
4183
4183
|
},
|
|
@@ -4195,7 +4195,7 @@
|
|
|
4195
4195
|
"surface": "builders-hall",
|
|
4196
4196
|
"text": "Could not set up key storage. Try again.",
|
|
4197
4197
|
"file": "modules/hall-ui/public/settings.js",
|
|
4198
|
-
"line":
|
|
4198
|
+
"line": 1133,
|
|
4199
4199
|
"origin": "js-notice",
|
|
4200
4200
|
"confidence": "certain"
|
|
4201
4201
|
},
|
|
@@ -4204,7 +4204,7 @@
|
|
|
4204
4204
|
"surface": "builders-hall",
|
|
4205
4205
|
"text": "Could not set up storage. Try again.",
|
|
4206
4206
|
"file": "modules/hall-ui/public/settings.js",
|
|
4207
|
-
"line":
|
|
4207
|
+
"line": 1132,
|
|
4208
4208
|
"origin": "js-text-assign",
|
|
4209
4209
|
"confidence": "certain"
|
|
4210
4210
|
},
|
|
@@ -4883,15 +4883,6 @@
|
|
|
4883
4883
|
"origin": "html-text",
|
|
4884
4884
|
"confidence": "certain"
|
|
4885
4885
|
},
|
|
4886
|
-
{
|
|
4887
|
-
"id": "d629e152f074",
|
|
4888
|
-
"surface": "builders-hall",
|
|
4889
|
-
"text": "Expires {…} · refreshes on use.",
|
|
4890
|
-
"file": "modules/hall-ui/public/settings.js",
|
|
4891
|
-
"line": 939,
|
|
4892
|
-
"origin": "js-text-assign",
|
|
4893
|
-
"confidence": "certain"
|
|
4894
|
-
},
|
|
4895
4886
|
{
|
|
4896
4887
|
"id": "de62f4cc7d2e",
|
|
4897
4888
|
"surface": "builders-hall",
|
|
@@ -5104,7 +5095,7 @@
|
|
|
5104
5095
|
"surface": "builders-hall",
|
|
5105
5096
|
"text": "Fresh CLI token issued. Paste it in your terminal:",
|
|
5106
5097
|
"file": "modules/hall-ui/public/settings.js",
|
|
5107
|
-
"line":
|
|
5098
|
+
"line": 932,
|
|
5108
5099
|
"origin": "js-text-assign",
|
|
5109
5100
|
"confidence": "certain"
|
|
5110
5101
|
},
|
|
@@ -5185,7 +5176,7 @@
|
|
|
5185
5176
|
"surface": "builders-hall",
|
|
5186
5177
|
"text": "Get a free key ↗",
|
|
5187
5178
|
"file": "modules/hall-ui/public/settings.js",
|
|
5188
|
-
"line":
|
|
5179
|
+
"line": 976,
|
|
5189
5180
|
"origin": "js-markup",
|
|
5190
5181
|
"confidence": "certain"
|
|
5191
5182
|
},
|
|
@@ -5734,7 +5725,7 @@
|
|
|
5734
5725
|
"surface": "builders-hall",
|
|
5735
5726
|
"text": "Image key removed.",
|
|
5736
5727
|
"file": "modules/hall-ui/public/settings.js",
|
|
5737
|
-
"line":
|
|
5728
|
+
"line": 1149,
|
|
5738
5729
|
"origin": "js-notice",
|
|
5739
5730
|
"confidence": "certain"
|
|
5740
5731
|
},
|
|
@@ -5977,7 +5968,7 @@
|
|
|
5977
5968
|
"surface": "builders-hall",
|
|
5978
5969
|
"text": "Key removed.",
|
|
5979
5970
|
"file": "modules/hall-ui/public/settings.js",
|
|
5980
|
-
"line":
|
|
5971
|
+
"line": 1148,
|
|
5981
5972
|
"origin": "js-text-assign",
|
|
5982
5973
|
"confidence": "certain"
|
|
5983
5974
|
},
|
|
@@ -5986,7 +5977,7 @@
|
|
|
5986
5977
|
"surface": "builders-hall",
|
|
5987
5978
|
"text": "Key storage is being set up by an Archon — check back shortly. {…}",
|
|
5988
5979
|
"file": "modules/hall-ui/public/settings.js",
|
|
5989
|
-
"line":
|
|
5980
|
+
"line": 1027,
|
|
5990
5981
|
"origin": "js-markup",
|
|
5991
5982
|
"confidence": "certain"
|
|
5992
5983
|
},
|
|
@@ -5995,7 +5986,7 @@
|
|
|
5995
5986
|
"surface": "builders-hall",
|
|
5996
5987
|
"text": "Key storage isn't set up yet. As an Archon you can turn it on now — the server generates and safely stores the master key (no terminal needed).",
|
|
5997
5988
|
"file": "modules/hall-ui/public/settings.js",
|
|
5998
|
-
"line":
|
|
5989
|
+
"line": 1023,
|
|
5999
5990
|
"origin": "js-markup",
|
|
6000
5991
|
"confidence": "certain"
|
|
6001
5992
|
},
|
|
@@ -6058,7 +6049,7 @@
|
|
|
6058
6049
|
"surface": "builders-hall",
|
|
6059
6050
|
"text": "Latest version: v{…}.",
|
|
6060
6051
|
"file": "modules/hall-ui/public/settings.js",
|
|
6061
|
-
"line":
|
|
6052
|
+
"line": 1421,
|
|
6062
6053
|
"origin": "js-text-assign",
|
|
6063
6054
|
"confidence": "certain"
|
|
6064
6055
|
},
|
|
@@ -6733,7 +6724,7 @@
|
|
|
6733
6724
|
"surface": "builders-hall",
|
|
6734
6725
|
"text": "No builder account found for this sign-in.",
|
|
6735
6726
|
"file": "modules/hall-ui/public/settings.js",
|
|
6736
|
-
"line":
|
|
6727
|
+
"line": 1340,
|
|
6737
6728
|
"origin": "js-text-assign",
|
|
6738
6729
|
"confidence": "certain"
|
|
6739
6730
|
},
|
|
@@ -7498,7 +7489,7 @@
|
|
|
7498
7489
|
"surface": "builders-hall",
|
|
7499
7490
|
"text": "Paste command copied.",
|
|
7500
7491
|
"file": "modules/hall-ui/public/settings.js",
|
|
7501
|
-
"line":
|
|
7492
|
+
"line": 951,
|
|
7502
7493
|
"origin": "js-notice",
|
|
7503
7494
|
"confidence": "certain"
|
|
7504
7495
|
},
|
|
@@ -7507,7 +7498,7 @@
|
|
|
7507
7498
|
"surface": "builders-hall",
|
|
7508
7499
|
"text": "Paste your key first.",
|
|
7509
7500
|
"file": "modules/hall-ui/public/settings.js",
|
|
7510
|
-
"line":
|
|
7501
|
+
"line": 1072,
|
|
7511
7502
|
"origin": "js-notice",
|
|
7512
7503
|
"confidence": "certain"
|
|
7513
7504
|
},
|
|
@@ -7921,7 +7912,7 @@
|
|
|
7921
7912
|
"surface": "builders-hall",
|
|
7922
7913
|
"text": "Re-issue failed: {…}",
|
|
7923
7914
|
"file": "modules/hall-ui/public/settings.js",
|
|
7924
|
-
"line":
|
|
7915
|
+
"line": 956,
|
|
7925
7916
|
"origin": "js-notice",
|
|
7926
7917
|
"confidence": "certain"
|
|
7927
7918
|
},
|
|
@@ -8182,7 +8173,7 @@
|
|
|
8182
8173
|
"surface": "builders-hall",
|
|
8183
8174
|
"text": "Remove your image-generation key? Art generation will stop until you add one again.",
|
|
8184
8175
|
"file": "modules/hall-ui/public/settings.js",
|
|
8185
|
-
"line":
|
|
8176
|
+
"line": 1140,
|
|
8186
8177
|
"origin": "js-notice",
|
|
8187
8178
|
"confidence": "certain"
|
|
8188
8179
|
},
|
|
@@ -8488,7 +8479,7 @@
|
|
|
8488
8479
|
"surface": "builders-hall",
|
|
8489
8480
|
"text": "Save key",
|
|
8490
8481
|
"file": "modules/hall-ui/public/settings.js",
|
|
8491
|
-
"line":
|
|
8482
|
+
"line": 1008,
|
|
8492
8483
|
"origin": "js-markup",
|
|
8493
8484
|
"confidence": "certain"
|
|
8494
8485
|
},
|
|
@@ -8749,7 +8740,7 @@
|
|
|
8749
8740
|
"surface": "builders-hall",
|
|
8750
8741
|
"text": "Set up key storage",
|
|
8751
8742
|
"file": "modules/hall-ui/public/settings.js",
|
|
8752
|
-
"line":
|
|
8743
|
+
"line": 1024,
|
|
8753
8744
|
"origin": "js-markup",
|
|
8754
8745
|
"confidence": "certain"
|
|
8755
8746
|
},
|
|
@@ -8767,7 +8758,7 @@
|
|
|
8767
8758
|
"surface": "builders-hall",
|
|
8768
8759
|
"text": "Setting up key storage…",
|
|
8769
8760
|
"file": "modules/hall-ui/public/settings.js",
|
|
8770
|
-
"line":
|
|
8761
|
+
"line": 1108,
|
|
8771
8762
|
"origin": "js-text-assign",
|
|
8772
8763
|
"confidence": "certain"
|
|
8773
8764
|
},
|
|
@@ -11017,7 +11008,7 @@
|
|
|
11017
11008
|
"surface": "builders-hall",
|
|
11018
11009
|
"text": "Your image-generation key settings could not be loaded. Reload the page to try again.",
|
|
11019
11010
|
"file": "modules/hall-ui/public/settings.js",
|
|
11020
|
-
"line":
|
|
11011
|
+
"line": 1175,
|
|
11021
11012
|
"origin": "js-markup",
|
|
11022
11013
|
"confidence": "certain"
|
|
11023
11014
|
},
|
|
@@ -11035,7 +11026,7 @@
|
|
|
11035
11026
|
"surface": "builders-hall",
|
|
11036
11027
|
"text": "Your key",
|
|
11037
11028
|
"file": "modules/hall-ui/public/settings.js",
|
|
11038
|
-
"line":
|
|
11029
|
+
"line": 1004,
|
|
11039
11030
|
"origin": "js-markup",
|
|
11040
11031
|
"confidence": "certain"
|
|
11041
11032
|
},
|
|
@@ -11107,7 +11098,7 @@
|
|
|
11107
11098
|
"surface": "builders-hall",
|
|
11108
11099
|
"text": "Your preferences, {…}.",
|
|
11109
11100
|
"file": "modules/hall-ui/public/settings.js",
|
|
11110
|
-
"line":
|
|
11101
|
+
"line": 1349,
|
|
11111
11102
|
"origin": "js-text-assign",
|
|
11112
11103
|
"confidence": "certain"
|
|
11113
11104
|
},
|
|
@@ -12196,7 +12187,7 @@
|
|
|
12196
12187
|
"surface": "builders-hall",
|
|
12197
12188
|
"text": "paste command",
|
|
12198
12189
|
"file": "modules/hall-ui/public/settings.js",
|
|
12199
|
-
"line":
|
|
12190
|
+
"line": 934,
|
|
12200
12191
|
"origin": "js-text-assign",
|
|
12201
12192
|
"confidence": "certain"
|
|
12202
12193
|
},
|
|
@@ -13078,7 +13069,7 @@
|
|
|
13078
13069
|
"surface": "builders-hall",
|
|
13079
13070
|
"text": "{…} · Stored encrypted; never shown again after saving.",
|
|
13080
13071
|
"file": "modules/hall-ui/public/settings.js",
|
|
13081
|
-
"line":
|
|
13072
|
+
"line": 1010,
|
|
13082
13073
|
"origin": "js-markup",
|
|
13083
13074
|
"confidence": "certain"
|
|
13084
13075
|
},
|
|
@@ -13091,6 +13082,15 @@
|
|
|
13091
13082
|
"origin": "js-markup",
|
|
13092
13083
|
"confidence": "certain"
|
|
13093
13084
|
},
|
|
13085
|
+
{
|
|
13086
|
+
"id": "a6e4ed98fbea",
|
|
13087
|
+
"surface": "builders-hall",
|
|
13088
|
+
"text": "{…} · revoke it any time under Active sessions.",
|
|
13089
|
+
"file": "modules/hall-ui/public/settings.js",
|
|
13090
|
+
"line": 942,
|
|
13091
|
+
"origin": "js-text-assign",
|
|
13092
|
+
"confidence": "certain"
|
|
13093
|
+
},
|
|
13094
13094
|
{
|
|
13095
13095
|
"id": "d73256fbc395",
|
|
13096
13096
|
"surface": "builders-hall",
|
|
@@ -2056,5 +2056,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2056
2056
|
landed since 1.19.789 with no explicit bump. run 35163350575. (task 1002620)
|
|
2057
2057
|
1.19.791 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2058
2058
|
landed since 1.19.790 with no explicit bump. run 35165066743. (task 1002620)
|
|
2059
|
+
1.19.792 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2060
|
+
landed since 1.19.791 with no explicit bump. run 35166486577. (task 1002620)
|
|
2059
2061
|
---------------------------------------------------------------------------
|
|
2060
2062
|
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
-- core_243 — CLI sessions lose their idle expiry (task 1003956, ADR 0294).
|
|
2
|
+
--
|
|
3
|
+
-- WHAT CHANGED IN CODE. db-kernel.js createSession now records NO expiry when a
|
|
4
|
+
-- caller names none (every such caller is source='cli'), and lookupSession's
|
|
5
|
+
-- refresh-on-use rolls expires_at forward only for a row that already has one.
|
|
6
|
+
-- Both halves are forward-looking: they govern sessions minted or used AFTER the
|
|
7
|
+
-- deploy. Neither touches the dated rows already sitting in the table.
|
|
8
|
+
--
|
|
9
|
+
-- WHY THAT NEEDS A MIGRATION. Without this, the code change would be nearly
|
|
10
|
+
-- invisible on the day it ships. Every live CLI session carries an expires_at
|
|
11
|
+
-- from migration 035's backfill and from every refresh since, so each one would
|
|
12
|
+
-- still lapse on its own 24h clock exactly as before — and each builder would eat
|
|
13
|
+
-- one final forced re-auth to get a row the new default applies to. That is the
|
|
14
|
+
-- precise annoyance the task set out to remove, delivered once more on the way
|
|
15
|
+
-- out. Clearing the column here is what makes the fix arrive for people who are
|
|
16
|
+
-- already signed in.
|
|
17
|
+
--
|
|
18
|
+
-- DIRECTION OF THE GRACE. Migration 035 faced the mirror of this and reasoned the
|
|
19
|
+
-- same way: it backfilled a 24h runway specifically so introducing a TTL would
|
|
20
|
+
-- not kill the session running the migration. This is that courtesy inverted —
|
|
21
|
+
-- 035 pushed expiries out so nobody was signed out by a new timer; this removes
|
|
22
|
+
-- them so nobody is signed out by a timer already gone from the code. In both
|
|
23
|
+
-- cases the migration exists to keep a policy change off the backs of the people
|
|
24
|
+
-- holding live sessions when it lands.
|
|
25
|
+
--
|
|
26
|
+
-- WHY source='cli' AND NOT A BLANKET UPDATE. builder_sessions holds both classes
|
|
27
|
+
-- and only the CLI's expiry was asked for. A web row's expires_at is an explicit
|
|
28
|
+
-- 30-day value its own flow chose (auth-idp.js / auth-github.js pass a real date,
|
|
29
|
+
-- so the new NULL default never reaches them); nulling it here would silently
|
|
30
|
+
-- hand browser cookies an immortality nobody decided on, and the code would not
|
|
31
|
+
-- re-establish it — lookupSession only rolls an expiry it can already see, so a
|
|
32
|
+
-- web row cleared by mistake stays cleared forever. The filter is the whole
|
|
33
|
+
-- safety property of this statement.
|
|
34
|
+
--
|
|
35
|
+
-- WHY revoked_at IS NULL. A revoked row is dead by revoked_at, which lookupSession
|
|
36
|
+
-- checks before it ever reads expires_at, so clearing its expiry could not revive
|
|
37
|
+
-- it. It is excluded anyway: revoked rows are the audit trail of sessions somebody
|
|
38
|
+
-- deliberately killed, and rewriting their columns muddies what that record says.
|
|
39
|
+
-- Touch only what the change is actually about.
|
|
40
|
+
--
|
|
41
|
+
-- WHAT THIS DOES NOT WEAKEN. Revocation is untouched and remains the real remedy
|
|
42
|
+
-- (ADR 0206): POST /me/sessions/revoke and "Sign out everywhere" kill a leaked
|
|
43
|
+
-- bearer immediately, setBuilderRank sweeps every session on demotion, and
|
|
44
|
+
-- requireBuilder refuses a deactivated builder on the hot path regardless of any
|
|
45
|
+
-- live token. None of those consult expires_at.
|
|
46
|
+
--
|
|
47
|
+
-- Idempotent: re-running matches no rows the second time (expires_at is already
|
|
48
|
+
-- NULL) and is a no-op.
|
|
49
|
+
|
|
50
|
+
BEGIN;
|
|
51
|
+
|
|
52
|
+
UPDATE builder_sessions
|
|
53
|
+
SET expires_at = NULL
|
|
54
|
+
WHERE source = 'cli'
|
|
55
|
+
AND revoked_at IS NULL
|
|
56
|
+
AND expires_at IS NOT NULL;
|
|
57
|
+
|
|
58
|
+
COMMIT;
|
|
@@ -913,7 +913,10 @@
|
|
|
913
913
|
if (res.status === 401) { toAuth(); return; }
|
|
914
914
|
const body = (res.data || {});
|
|
915
915
|
if (!res.ok) throw new Error(body.message || `HTTP ${res.status}`);
|
|
916
|
-
|
|
916
|
+
// No expires_at is the NORMAL case for a CLI bearer since ADR 0294 — say so
|
|
917
|
+
// plainly. 'unknown' read as a gap in the page's knowledge; the absence of a
|
|
918
|
+
// date is the fact, and the revoke is what replaced the timer.
|
|
919
|
+
const expires = body.expires_at ? `Expires ${new Date(body.expires_at).toLocaleString()}` : 'Never expires';
|
|
917
920
|
const pasteCommand = body.paste_command || '';
|
|
918
921
|
// The secret is QUOTED (settings.css `.quote`): a 64-character token cannot
|
|
919
922
|
// be a line of prose, so it sits one tonal step down with its own foot. Same
|
|
@@ -936,7 +939,7 @@
|
|
|
936
939
|
copyBtn.id = 'cli-reissue-copy';
|
|
937
940
|
copyBtn.textContent = 'Copy';
|
|
938
941
|
const hint = el('span', 'settings-card__hint');
|
|
939
|
-
hint.textContent =
|
|
942
|
+
hint.textContent = `${expires} · revoke it any time under Active sessions.`;
|
|
940
943
|
const foot = el('div', 'quote__foot');
|
|
941
944
|
foot.append(copyBtn, hint);
|
|
942
945
|
const quote = el('div', 'quote');
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.792",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.792",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.792",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
|
@@ -93,7 +93,7 @@ async function probeMe(tokenInfo) {
|
|
|
93
93
|
function printReauth({ boxScoped }) {
|
|
94
94
|
const why = boxScoped
|
|
95
95
|
? 'This box holds the BOX-SCOPED bootstrap token (source=box, ADR 0053) — it can bootstrap the box but is refused (403) on claim / ship / publish.'
|
|
96
|
-
: 'This session token is
|
|
96
|
+
: 'This session token is REVOKED or otherwise rejected (CLI tokens do not expire on their own — ADR 0294).';
|
|
97
97
|
console.log('[otb] ── dev box: RE-AUTH BEFORE YOU WORK ──');
|
|
98
98
|
console.log(`[otb] ${why}`);
|
|
99
99
|
console.log('[otb] ⚠ FIRST STEP this session: get the builder onto a real CLI session BEFORE claiming or shipping —');
|
package/scripts/gds/cli-lib.js
CHANGED
|
@@ -521,9 +521,9 @@ function printUnauthGuidanceAndExit() {
|
|
|
521
521
|
}
|
|
522
522
|
console.error('');
|
|
523
523
|
console.error(' Possible causes:');
|
|
524
|
-
console.error(' - Your
|
|
525
|
-
console.error(' - Your token was revoked by an Archon');
|
|
524
|
+
console.error(' - Your token was revoked — by you ("Sign out everywhere") or by an Archon');
|
|
526
525
|
console.error(' - A recent deploy applied an auth-changing migration (see deploy banner)');
|
|
526
|
+
console.error(' - This instance is older than ADR 0294 and still expires idle CLI sessions');
|
|
527
527
|
console.error('');
|
|
528
528
|
console.error(' Once re-authed, re-run whichever command you were trying.');
|
|
529
529
|
// `doctor` is checkout-only — it is not one of the public CLI's verbs (ADR 0258).
|
package/scripts/gds/reauth.js
CHANGED
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
//
|
|
4
4
|
// The fast, UI-first path to refresh an expired/invalid GDS CLI session.
|
|
5
5
|
//
|
|
6
|
-
// Why this exists: CLI
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
6
|
+
// Why this exists: a CLI session can stop working — revoked from the hall's
|
|
7
|
+
// "Sign out everywhere", swept by a demotion, or invalidated by an auth-changing
|
|
8
|
+
// deploy. (It no longer stops working from mere disuse: ADR 0294 removed the idle
|
|
9
|
+
// expiry, because the timer only ever signed out the legitimate holder while
|
|
10
|
+
// refresh-on-use kept a thief's copy alive.) Whatever killed it, the friction of
|
|
11
|
+
// getting back in — the slow Device Flow, terminal codes, Gemini-key prompts — is
|
|
12
|
+
// not something to keep. This script is the fix:
|
|
11
13
|
//
|
|
12
14
|
// 1. Detect — is the current session still valid? (GET /api/gds/me)
|
|
13
15
|
// valid → print who you are + exit 0. Nothing to do.
|
|
@@ -133,8 +135,8 @@ async function main() {
|
|
|
133
135
|
const b = (res.data && res.data.builder) || {};
|
|
134
136
|
console.log(`Your GDS CLI session is valid — no re-auth needed.`);
|
|
135
137
|
console.log(` Signed in as ${b.github_login || '?'}${b.rank ? ` (rank: ${b.rank})` : ''}.`);
|
|
136
|
-
console.log(' (
|
|
137
|
-
console.log('
|
|
138
|
+
console.log(' (CLI sessions do not expire — they last until revoked. Kill one from');
|
|
139
|
+
console.log(' Settings → Active sessions, or "Sign out everywhere".)');
|
|
138
140
|
process.exit(0);
|
|
139
141
|
}
|
|
140
142
|
|
|
@@ -145,6 +145,13 @@ const INTEGRATION = new Set([
|
|
|
145
145
|
// prove the CHECK actually refuses a stored fourth state, that the backfill lands on a
|
|
146
146
|
// pre-migration row, and that publishableSql and projectPublishability agree.
|
|
147
147
|
'project_visibility_db',
|
|
148
|
+
// task 1003956 (ADR 0294): that CLI sessions really never expire. The DB-free
|
|
149
|
+
// sibling (auth_session_ttl) pins the constant, createSession's value against a
|
|
150
|
+
// stub pool, and the TEXT of the refresh statement — but a regex over source
|
|
151
|
+
// proves the characters are there, not that Postgres does what they mean. Only a
|
|
152
|
+
// real engine can show the CASE guard leaving a NULL alone on an actual use,
|
|
153
|
+
// which is exactly where the removed timeout would come back.
|
|
154
|
+
'auth_session_expiry_db',
|
|
148
155
|
'scouting_rollup_fanout', 'session_records',
|
|
149
156
|
// task 1003217: the cost-row RAISE against real SQL. Every claim in it IS the
|
|
150
157
|
// SQL — an ON CONFLICT DO UPDATE guarded to move a row only upward, and a
|
|
@@ -218,6 +218,8 @@ async function pollDeviceFlow(deviceCode, userAgent) {
|
|
|
218
218
|
source: 'cli',
|
|
219
219
|
userAgent: userAgent ?? null,
|
|
220
220
|
// CLI tokens have no expiry (manually revocable). Web tokens expire.
|
|
221
|
+
// True again as of ADR 0294: migration 035 made this line a lie for two years
|
|
222
|
+
// by defaulting a null to a TTL, and removing that default restored it.
|
|
221
223
|
expiresAt: null,
|
|
222
224
|
});
|
|
223
225
|
// V3.R75 (#294): tick the onboarding state machine. Best-effort — auth
|
package/src/bongos/db-kernel.js
CHANGED
|
@@ -262,16 +262,25 @@ async function accessStateByLogin(login) {
|
|
|
262
262
|
|
|
263
263
|
// --- Auth sessions (kernel: the builder_sessions token store auth.js drives) ----
|
|
264
264
|
|
|
265
|
-
// SESSION_TTL_MS —
|
|
266
|
-
//
|
|
265
|
+
// SESSION_TTL_MS — the roll-forward window for a session that HAS an expiry.
|
|
266
|
+
// It is no longer a default: a caller that names no expiry gets none (ADR 0294).
|
|
267
|
+
// What still reads it is refresh-on-use below, which rolls an already-dated row
|
|
268
|
+
// (the web flow's) forward on each request. Centralized so the tests and the
|
|
269
|
+
// code agree on one number.
|
|
267
270
|
const SESSION_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
268
271
|
|
|
269
|
-
// createSession — mint a builder_sessions row.
|
|
270
|
-
//
|
|
272
|
+
// createSession — mint a builder_sessions row.
|
|
273
|
+
//
|
|
274
|
+
// A null/undefined expiresAt means NO EXPIRY (expires_at NULL), which
|
|
275
|
+
// lookupSession honours as never-expires. That is the CLI's contract (ADR 0294,
|
|
276
|
+
// restoring 003_pms.sql's original one): a `bongos` sign-in lasts until it is
|
|
277
|
+
// revoked, because an idle expiry only ever logged out the legitimate holder —
|
|
278
|
+
// the remedy for a leaked bearer is the own-scoped revoke of ADR 0206, which is
|
|
279
|
+
// immediate where a timer is not. Every caller that passes null is source='cli'.
|
|
280
|
+
//
|
|
281
|
+
// Web callers pass an explicit date (30 days) and are untouched by this default.
|
|
271
282
|
async function createSession({ builderId, token, source, userAgent, expiresAt }) {
|
|
272
|
-
const effectiveExpiresAt = expiresAt
|
|
273
|
-
? new Date(Date.now() + SESSION_TTL_MS)
|
|
274
|
-
: expiresAt;
|
|
283
|
+
const effectiveExpiresAt = expiresAt ?? null;
|
|
275
284
|
const { rows } = await pool.query(
|
|
276
285
|
`INSERT INTO builder_sessions (builder_id, token, source, user_agent, expires_at)
|
|
277
286
|
VALUES ($1, $2, $3, $4, $5)
|
|
@@ -282,9 +291,10 @@ async function createSession({ builderId, token, source, userAgent, expiresAt })
|
|
|
282
291
|
}
|
|
283
292
|
|
|
284
293
|
// lookupSession — resolve a live (unrevoked, unexpired) session token to its
|
|
285
|
-
// builder identity, and refresh-on-use (bump last_used_at
|
|
286
|
-
// fire-and-forget). Returns null for
|
|
287
|
-
//
|
|
294
|
+
// builder identity, and refresh-on-use (bump last_used_at, and roll expiry
|
|
295
|
+
// forward for a row that has one, fire-and-forget). Returns null for
|
|
296
|
+
// missing/revoked/expired; a row with expires_at NULL never expires. Read fresh
|
|
297
|
+
// per request, never cached (ADR 0016).
|
|
288
298
|
//
|
|
289
299
|
// The governance FOLD (task 1002556): when the governance module is enabled, the
|
|
290
300
|
// same round-trip also aggregates the builder's raw permission grant keys, so
|
|
@@ -335,11 +345,19 @@ async function lookupSession(token) {
|
|
|
335
345
|
if (!row) return null;
|
|
336
346
|
if (row.revoked_at) return null;
|
|
337
347
|
if (row.expires_at && row.expires_at < new Date()) return null;
|
|
348
|
+
// Refresh-on-use. last_used_at always moves — the own-sessions list (ADR 0206)
|
|
349
|
+
// is how a person spots a session they don't recognise, and that reading is the
|
|
350
|
+
// whole remedy now that CLI rows never lapse. expires_at only rolls forward for
|
|
351
|
+
// a row that HAS one: the CASE is what stops a use from minting an expiry on a
|
|
352
|
+
// never-expires row and quietly reintroducing the timeout per ADR 0294.
|
|
338
353
|
pool
|
|
339
354
|
.query(
|
|
340
355
|
`UPDATE builder_sessions
|
|
341
356
|
SET last_used_at = now(),
|
|
342
|
-
expires_at =
|
|
357
|
+
expires_at = CASE
|
|
358
|
+
WHEN expires_at IS NULL THEN NULL
|
|
359
|
+
ELSE now() + ($2::int * INTERVAL '1 millisecond')
|
|
360
|
+
END
|
|
343
361
|
WHERE id = $1`,
|
|
344
362
|
[row.session_id, SESSION_TTL_MS]
|
|
345
363
|
)
|