@noodleseed/one 0.63.0 → 0.63.1
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/node_modules/@noodle-borg/service/dist/oauth/branding.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/oauth/branding.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/branding.js +3 -2
- package/node_modules/@noodle-borg/service/dist/oauth/branding.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.js +216 -28
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.js.map +1 -1
- package/package.json +1 -1
|
@@ -20,6 +20,8 @@ export interface OAuthPageInput {
|
|
|
20
20
|
readonly heading: string;
|
|
21
21
|
/** Pre-escaped inner HTML (lede, detail list, form). Callers own their own escaping. */
|
|
22
22
|
readonly contentHtml: string;
|
|
23
|
+
/** Optional trusted static CSS appended after the shared OAuth styles. */
|
|
24
|
+
readonly additionalStyles?: string;
|
|
23
25
|
/** Optional pre-built `<script>` block appended before `</body>` (e.g. the customer sign-in module). */
|
|
24
26
|
readonly scriptHtml?: string;
|
|
25
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../../src/oauth/branding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"branding.d.ts","sourceRoot":"","sources":["../../src/oauth/branding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkLH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oBAAoB;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,wFAAwF;IACxF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,wGAAwG;IACxG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,oGAAoG;AACpG,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CA+B7D;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,IAAI,MAAM,CAQ7C"}
|
|
@@ -120,7 +120,7 @@ body{
|
|
|
120
120
|
margin:0;min-height:100dvh;background:var(--bg);color:var(--fg);
|
|
121
121
|
font-family:"Geist",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
|
|
122
122
|
-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
|
|
123
|
-
display:
|
|
123
|
+
display:flex;justify-content:center;align-items:flex-start;padding:24px;position:relative;overflow:auto;
|
|
124
124
|
}
|
|
125
125
|
/* WebGL grain-gradient canvas over an on-brand CSS radial-gradient fallback. */
|
|
126
126
|
.ns-canvas{position:fixed;inset:0;width:100%;height:100%;z-index:-4;display:block;pointer-events:none}
|
|
@@ -139,6 +139,7 @@ body{
|
|
|
139
139
|
border:1px solid var(--border);border-radius:1.1rem;background:var(--card);
|
|
140
140
|
-webkit-backdrop-filter:blur(16px) saturate(1.2);backdrop-filter:blur(16px) saturate(1.2);
|
|
141
141
|
padding:1.9rem;
|
|
142
|
+
margin:auto 0;
|
|
142
143
|
box-shadow:0 30px 90px -45px rgba(0,0,0,.9),0 0 0 1px rgba(255,255,255,.02),inset 0 1px 0 0 rgba(255,255,255,.06);
|
|
143
144
|
}
|
|
144
145
|
.ns-head{display:flex;align-items:center;margin-bottom:1.6rem}
|
|
@@ -193,7 +194,7 @@ export function renderOAuthPage(input) {
|
|
|
193
194
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
194
195
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
195
196
|
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
196
|
-
<style>${STYLES}</style>
|
|
197
|
+
<style>${STYLES}${input.additionalStyles ?? ''}</style>
|
|
197
198
|
</head>
|
|
198
199
|
<body>
|
|
199
200
|
<canvas id="ns-canvas" class="ns-canvas" aria-hidden="true"></canvas>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branding.js","sourceRoot":"","sources":["../../src/oauth/branding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,SAAS,GAAG,CAAC,KAAa;IACxB,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,2FAA2F;AAC3F,MAAM,OAAO,GAAG,sBAAsB,kBAAkB,CACtD,0nBAA0nB,CAC3nB,EAAE,CAAC;AAEJ,8GAA8G;AAC9G,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;OAcV,CAAC;AAER;;;;;GAKG;AACH,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA6DZ,CAAC;AAEX,0GAA0G;AAC1G,MAAM,MAAM,GAAG
|
|
1
|
+
{"version":3,"file":"branding.js","sourceRoot":"","sources":["../../src/oauth/branding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,SAAS,GAAG,CAAC,KAAa;IACxB,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,2FAA2F;AAC3F,MAAM,OAAO,GAAG,sBAAsB,kBAAkB,CACtD,0nBAA0nB,CAC3nB,EAAE,CAAC;AAEJ,8GAA8G;AAC9G,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;OAcV,CAAC;AAER;;;;;GAKG;AACH,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA6DZ,CAAC;AAEX,0GAA0G;AAC1G,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0EAyE2D,CAAC;AAiB3E,oGAAoG;AACpG,MAAM,UAAU,eAAe,CAAC,KAAqB;IACnD,OAAO;;;;;;;SAOA,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;8CACqB,OAAO;;;;SAI5C,MAAM,GAAG,KAAK,CAAC,gBAAgB,IAAI,EAAE;;;;;;;;;yBASrB,QAAQ;yBACR,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;yBACjB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;IACvC,KAAK,CAAC,WAAW;;EAEnB,aAAa;EACb,KAAK,CAAC,UAAU,IAAI,EAAE;;QAEhB,CAAC;AACT,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,oBAAoB;IAClC,OAAO,eAAe,CAAC;QACrB,KAAK,EAAE,6BAA6B;QACpC,MAAM,EAAE,OAAO;QACf,OAAO,EAAE,eAAe;QACxB,WAAW,EACT,6HAA6H;KAChI,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"developer-grant-page.d.ts","sourceRoot":"","sources":["../../src/oauth/developer-grant-page.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;
|
|
1
|
+
{"version":3,"file":"developer-grant-page.d.ts","sourceRoot":"","sources":["../../src/oauth/developer-grant-page.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACnD;AA+HD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAuB/E"}
|
|
@@ -4,21 +4,133 @@ const CAPABILITY_COPY = {
|
|
|
4
4
|
'deployments:write': 'Build and deploy apps to the selected environments',
|
|
5
5
|
'deployments:rollback': 'Roll back deployments',
|
|
6
6
|
};
|
|
7
|
+
const ENVIRONMENT_PRIORITY = {
|
|
8
|
+
dev: 0,
|
|
9
|
+
staging: 1,
|
|
10
|
+
prod: 3,
|
|
11
|
+
};
|
|
12
|
+
const DEVELOPER_GRANT_STYLES = `
|
|
13
|
+
.ns-card{width:min(100%,46rem)}
|
|
14
|
+
.ns-title{max-width:38rem;white-space:normal}
|
|
15
|
+
.developer-context{grid-template-columns:repeat(3,minmax(0,1fr));gap:.75rem;margin-bottom:1.55rem}
|
|
16
|
+
.developer-context>div{min-width:0}
|
|
17
|
+
.developer-context .ns-dd{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
18
|
+
.developer-grant{display:grid;gap:1.35rem}
|
|
19
|
+
.developer-section{min-width:0;margin:0;padding:0;border:0}
|
|
20
|
+
.developer-step{display:flex;align-items:center;gap:.6rem;margin:0 0 .3rem;color:var(--fg);font-size:.94rem;font-weight:650}
|
|
21
|
+
.developer-step-number{display:grid;place-items:center;width:1.6rem;height:1.6rem;border:1px solid var(--border);border-radius:999px;color:var(--orange);font-size:.72rem}
|
|
22
|
+
.developer-help{margin:0 0 .8rem;color:var(--muted);font-size:.8rem;line-height:1.5}
|
|
23
|
+
.developer-org-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem}
|
|
24
|
+
.developer-org-choice{position:relative;display:block;min-width:0;cursor:pointer}
|
|
25
|
+
.developer-org-choice>input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
|
|
26
|
+
.developer-org-card{display:flex;align-items:center;justify-content:space-between;gap:.85rem;min-height:4rem;padding:.85rem .95rem;border:1px solid var(--border);border-radius:.8rem;background:rgba(255,255,255,.025);transition:border-color .16s ease,background .16s ease,box-shadow .16s ease}
|
|
27
|
+
.developer-org-choice:hover .developer-org-card{border-color:color-mix(in srgb,var(--border),var(--fg) 20%);background:rgba(255,255,255,.04)}
|
|
28
|
+
.developer-org-choice>input:focus-visible+.developer-org-card{outline:2px solid var(--orange);outline-offset:2px}
|
|
29
|
+
.developer-org-choice>input:checked+.developer-org-card{border-color:color-mix(in srgb,var(--orange) 70%,transparent);background:linear-gradient(135deg,color-mix(in srgb,var(--orange) 13%,transparent),rgba(255,255,255,.025));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--orange) 12%,transparent)}
|
|
30
|
+
.developer-org-name{display:block;overflow:hidden;color:var(--fg);font-size:.88rem;font-weight:650;text-overflow:ellipsis;white-space:nowrap}
|
|
31
|
+
.developer-org-access{display:block;margin-top:.18rem;color:var(--muted);font-size:.72rem}
|
|
32
|
+
.developer-choice-mark{display:grid;flex:0 0 auto;place-items:center;width:1.1rem;height:1.1rem;border:1px solid var(--border);border-radius:999px;color:transparent;font-size:.65rem}
|
|
33
|
+
.developer-org-choice>input:checked+.developer-org-card .developer-choice-mark{border-color:var(--orange);background:var(--orange);color:#130b07}
|
|
34
|
+
.developer-environment-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.6rem}
|
|
35
|
+
.developer-environment{position:relative;display:block;min-width:0;cursor:pointer}
|
|
36
|
+
.developer-environment>input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
|
|
37
|
+
.developer-environment-card{display:flex;align-items:flex-start;gap:.65rem;min-height:4.1rem;padding:.8rem;border:1px solid var(--border);border-radius:.75rem;background:rgba(255,255,255,.025);transition:border-color .16s ease,background .16s ease}
|
|
38
|
+
.developer-environment:hover .developer-environment-card{border-color:color-mix(in srgb,var(--border),var(--fg) 20%);background:rgba(255,255,255,.04)}
|
|
39
|
+
.developer-environment>input:focus-visible+.developer-environment-card{outline:2px solid var(--orange);outline-offset:2px}
|
|
40
|
+
.developer-environment>input:checked+.developer-environment-card{border-color:color-mix(in srgb,var(--orange) 70%,transparent);background:color-mix(in srgb,var(--orange) 10%,transparent)}
|
|
41
|
+
.developer-checkbox{display:grid;flex:0 0 auto;place-items:center;width:1rem;height:1rem;margin-top:.08rem;border:1px solid var(--border);border-radius:.25rem;color:transparent;font-size:.68rem}
|
|
42
|
+
.developer-environment>input:checked+.developer-environment-card .developer-checkbox{border-color:var(--orange);background:var(--orange);color:#130b07}
|
|
43
|
+
.developer-environment-name{display:block;color:var(--fg);font-size:.84rem;font-weight:650}
|
|
44
|
+
.developer-environment-note{display:block;margin-top:.2rem;color:var(--muted);font-size:.68rem;line-height:1.35}
|
|
45
|
+
.developer-environment-note.is-production{color:#f1a273}
|
|
46
|
+
.developer-capabilities{margin:.75rem 0 0;padding:.7rem .8rem;border:1px solid var(--border);border-radius:.7rem;background:rgba(0,0,0,.12);color:var(--muted);font-size:.75rem}
|
|
47
|
+
.developer-capabilities summary{cursor:pointer;color:var(--fg);font-weight:600}
|
|
48
|
+
.developer-capabilities ul{display:grid;gap:.35rem;margin:.6rem 0 0;padding-left:1.15rem;line-height:1.45}
|
|
49
|
+
.developer-summary{padding:.85rem .95rem;border:1px solid var(--border);border-radius:.75rem;background:rgba(255,255,255,.025)}
|
|
50
|
+
.developer-summary-label{margin:0 0 .24rem;color:var(--muted);font-size:.65rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase}
|
|
51
|
+
.developer-summary-copy{margin:0;color:var(--fg);font-size:.8rem;line-height:1.5}
|
|
52
|
+
.developer-selection-error{margin:.45rem 0 0;color:#f1a273;font-size:.75rem}
|
|
53
|
+
.developer-grant .ns-row{margin-top:0}
|
|
54
|
+
.developer-grant .btn-primary:disabled{cursor:not-allowed;filter:none;opacity:.45}
|
|
55
|
+
@media(max-width:680px){
|
|
56
|
+
.ns-card{padding:1.35rem}
|
|
57
|
+
.developer-context,.developer-org-list,.developer-environment-grid{grid-template-columns:1fr}
|
|
58
|
+
.developer-context{gap:.55rem}
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
const DEVELOPER_GRANT_SCRIPT = `<script>
|
|
62
|
+
(function(){
|
|
63
|
+
var form=document.querySelector('[data-developer-grant]');
|
|
64
|
+
if(!form)return;
|
|
65
|
+
var choices=Array.from(form.querySelectorAll('[data-org-choice]'));
|
|
66
|
+
var panels=Array.from(form.querySelectorAll('[data-org-panel]'));
|
|
67
|
+
var authorize=form.querySelector('[data-authorize]');
|
|
68
|
+
var summary=form.querySelector('[data-selection-summary]');
|
|
69
|
+
var error=form.querySelector('[data-selection-error]');
|
|
70
|
+
var clientName=form.getAttribute('data-client-name')||'The developer plugin';
|
|
71
|
+
function activeIndex(){
|
|
72
|
+
var selected=choices.find(function(choice){return choice.checked;});
|
|
73
|
+
return selected ? Number(selected.getAttribute('data-org-choice')) : -1;
|
|
74
|
+
}
|
|
75
|
+
function activeEnvironments(){
|
|
76
|
+
var panel=panels[activeIndex()];
|
|
77
|
+
return panel ? Array.from(panel.querySelectorAll('input[name="environment"]:checked')).map(function(input){return input.value;}) : [];
|
|
78
|
+
}
|
|
79
|
+
function naturalList(values){
|
|
80
|
+
if(values.length<2)return values[0]||'';
|
|
81
|
+
if(values.length===2)return values[0]+' and '+values[1];
|
|
82
|
+
return values.slice(0,-1).join(', ')+', and '+values[values.length-1];
|
|
83
|
+
}
|
|
84
|
+
function update(){
|
|
85
|
+
var panel=panels[activeIndex()];
|
|
86
|
+
var environments=activeEnvironments();
|
|
87
|
+
var valid=panel!==undefined&&environments.length>0;
|
|
88
|
+
authorize.disabled=!valid;
|
|
89
|
+
error.hidden=valid;
|
|
90
|
+
if(valid){
|
|
91
|
+
summary.textContent=clientName+' can '+panel.getAttribute('data-capability-summary')+' in '+panel.getAttribute('data-org-name')+' for '+naturalList(environments)+'.';
|
|
92
|
+
}else{
|
|
93
|
+
summary.textContent='Select at least one environment to continue.';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
choices.forEach(function(choice){
|
|
97
|
+
choice.addEventListener('change',function(){
|
|
98
|
+
var next=activeIndex();
|
|
99
|
+
panels.forEach(function(panel,index){
|
|
100
|
+
var active=index===next;
|
|
101
|
+
panel.hidden=!active;
|
|
102
|
+
var environments=Array.from(panel.querySelectorAll('input[name="environment"]'));
|
|
103
|
+
environments.forEach(function(environment){environment.checked=false;environment.disabled=!active;});
|
|
104
|
+
if(active){
|
|
105
|
+
var preferred=environments.find(function(environment){return environment.value==='dev';});
|
|
106
|
+
if(preferred)preferred.checked=true;
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
update();
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
form.addEventListener('change',function(event){
|
|
113
|
+
if(event.target&&event.target.matches('input[name="environment"]'))update();
|
|
114
|
+
});
|
|
115
|
+
form.addEventListener('submit',function(event){
|
|
116
|
+
var submitter=event.submitter;
|
|
117
|
+
if(submitter&&submitter.value==='deny')return;
|
|
118
|
+
if(activeEnvironments().length===0){event.preventDefault();update();}
|
|
119
|
+
});
|
|
120
|
+
update();
|
|
121
|
+
})();
|
|
122
|
+
</script>`;
|
|
7
123
|
export function renderDeveloperGrantPage(input) {
|
|
8
|
-
const choices = input.choices.map(renderChoice).join('');
|
|
9
124
|
const controls = input.choices.length === 0
|
|
10
|
-
? '<p class="ns-note">No organizations are available for this account.</p>'
|
|
11
|
-
:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
</div
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<div><dt class="ns-dt">Signed in as</dt><dd class="ns-dd">${escapeHtml(input.userEmail)}</dd></div>
|
|
18
|
-
<div><dt class="ns-dt">Noodle Cloud</dt><dd class="ns-dd">${escapeHtml(input.resourceHost)}</dd></div>
|
|
19
|
-
<div><dt class="ns-dt">Redirects to</dt><dd class="ns-dd">${escapeHtml(input.redirectHost)}</dd></div>
|
|
125
|
+
? '<div class="ns-alert"><p class="ns-note">No organizations are available for this account.</p></div>'
|
|
126
|
+
: renderControls(input);
|
|
127
|
+
const contentHtml = `<p class="ns-lede">Review and choose the exact access for <strong>${escapeHtml(input.clientName)}</strong>. You can select more than one environment.</p>
|
|
128
|
+
<dl class="ns-dl developer-context">
|
|
129
|
+
<div><dt class="ns-dt">Signed in as</dt><dd class="ns-dd" title="${escapeHtml(input.userEmail)}">${escapeHtml(input.userEmail)}</dd></div>
|
|
130
|
+
<div><dt class="ns-dt">Noodle Cloud</dt><dd class="ns-dd" title="${escapeHtml(input.resourceHost)}">${escapeHtml(input.resourceHost)}</dd></div>
|
|
131
|
+
<div><dt class="ns-dt">Redirects to</dt><dd class="ns-dd" title="${escapeHtml(input.redirectHost)}">${escapeHtml(input.redirectHost)}</dd></div>
|
|
20
132
|
</dl>
|
|
21
|
-
<form method="post" action="${escapeHtml(input.grantAction)}">
|
|
133
|
+
<form method="post" action="${escapeHtml(input.grantAction)}" class="developer-grant" data-developer-grant data-client-name="${escapeHtml(input.clientName)}">
|
|
22
134
|
<input type="hidden" name="grant_token" value="${escapeHtml(input.grantToken)}" />
|
|
23
135
|
${controls}
|
|
24
136
|
</form>`;
|
|
@@ -27,28 +139,104 @@ export function renderDeveloperGrantPage(input) {
|
|
|
27
139
|
kicker: 'Developer access',
|
|
28
140
|
heading: 'Choose where this developer plugin can operate',
|
|
29
141
|
contentHtml,
|
|
142
|
+
additionalStyles: DEVELOPER_GRANT_STYLES,
|
|
143
|
+
...(input.choices.length === 0 ? {} : { scriptHtml: DEVELOPER_GRANT_SCRIPT }),
|
|
30
144
|
});
|
|
31
145
|
}
|
|
32
|
-
function
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
146
|
+
function renderControls(input) {
|
|
147
|
+
const organizations = input.choices.map(renderOrganizationChoice).join('');
|
|
148
|
+
const panels = input.choices.map(renderEnvironmentPanel).join('');
|
|
149
|
+
const first = input.choices[0];
|
|
150
|
+
const initialEnvironment = first?.environments.includes('dev') ? 'dev' : first?.environments[0];
|
|
151
|
+
const initialSummary = first !== undefined && initialEnvironment !== undefined
|
|
152
|
+
? `${input.clientName} can ${capabilitySummary(first.capabilities)} in ${first.displayName ?? first.org} for ${initialEnvironment}.`
|
|
153
|
+
: 'Select at least one environment to continue.';
|
|
154
|
+
return `<fieldset class="developer-section">
|
|
155
|
+
<legend class="developer-step"><span class="developer-step-number">1</span>Choose organization</legend>
|
|
156
|
+
<p class="developer-help">Only one organization can be authorized in this connection.</p>
|
|
157
|
+
<div class="developer-org-list">${organizations}</div>
|
|
158
|
+
</fieldset>
|
|
159
|
+
<div>${panels}</div>
|
|
160
|
+
<div class="developer-summary" aria-live="polite">
|
|
161
|
+
<p class="developer-summary-label">Access summary</p>
|
|
162
|
+
<p class="developer-summary-copy" data-selection-summary>${escapeHtml(initialSummary)}</p>
|
|
163
|
+
<p class="developer-selection-error" data-selection-error hidden>Select at least one environment to continue.</p>
|
|
164
|
+
</div>
|
|
165
|
+
<div class="ns-row">
|
|
166
|
+
<button type="submit" name="decision" value="deny" class="btn btn-ghost">Deny</button>
|
|
167
|
+
<span class="btn-glow"><button type="submit" name="decision" value="approve" class="btn btn-primary" data-authorize>Authorize access</button></span>
|
|
168
|
+
</div>`;
|
|
169
|
+
}
|
|
170
|
+
function renderOrganizationChoice(choice, index) {
|
|
171
|
+
const label = choice.displayName ?? choice.org;
|
|
172
|
+
const access = choice.capabilities.includes('deployments:rollback')
|
|
173
|
+
? 'Owner access'
|
|
174
|
+
: 'Developer access';
|
|
175
|
+
return `<label class="developer-org-choice">
|
|
176
|
+
<input type="radio" name="org" value="${escapeHtml(choice.org)}" data-org-choice="${index}"${index === 0 ? ' checked' : ''} />
|
|
177
|
+
<span class="developer-org-card">
|
|
178
|
+
<span><span class="developer-org-name">${escapeHtml(label)}</span><span class="developer-org-access">${access}</span></span>
|
|
179
|
+
<span class="developer-choice-mark" aria-hidden="true">✓</span>
|
|
180
|
+
</span>
|
|
181
|
+
</label>`;
|
|
182
|
+
}
|
|
183
|
+
function renderEnvironmentPanel(choice, choiceIndex) {
|
|
184
|
+
const environments = orderedEnvironments(choice.environments)
|
|
185
|
+
.map((environment, environmentIndex) => renderEnvironment(environment, choiceIndex, environmentIndex, choiceIndex === 0))
|
|
41
186
|
.join('');
|
|
42
187
|
const capabilities = choice.capabilities
|
|
43
188
|
.map((capability) => `<li>${escapeHtml(CAPABILITY_COPY[capability])}</li>`)
|
|
44
189
|
.join('');
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<
|
|
48
|
-
<
|
|
49
|
-
<
|
|
50
|
-
<
|
|
51
|
-
|
|
190
|
+
const label = choice.displayName ?? choice.org;
|
|
191
|
+
return `<section class="developer-section" data-org-panel="${choiceIndex}" data-org-name="${escapeHtml(label)}" data-capability-summary="${escapeHtml(capabilitySummary(choice.capabilities))}"${choiceIndex === 0 ? '' : ' hidden'}>
|
|
192
|
+
<h2 class="developer-step"><span class="developer-step-number">2</span>Choose environments</h2>
|
|
193
|
+
<p class="developer-help">Select every environment this plugin should be able to operate. Development is selected for you.</p>
|
|
194
|
+
<div class="developer-environment-grid">${environments}</div>
|
|
195
|
+
<details class="developer-capabilities">
|
|
196
|
+
<summary>What the plugin can do</summary>
|
|
197
|
+
<ul>${capabilities}</ul>
|
|
198
|
+
</details>
|
|
199
|
+
</section>`;
|
|
200
|
+
}
|
|
201
|
+
function renderEnvironment(environment, choiceIndex, environmentIndex, active) {
|
|
202
|
+
const id = `developer-environment-${choiceIndex}-${environmentIndex}`;
|
|
203
|
+
const selected = active && environment === 'dev';
|
|
204
|
+
const note = environmentNote(environment);
|
|
205
|
+
return `<label class="developer-environment" for="${id}">
|
|
206
|
+
<input id="${id}" type="checkbox" name="environment" value="${escapeHtml(environment)}"${selected ? ' checked' : ''}${active ? '' : ' disabled'} />
|
|
207
|
+
<span class="developer-environment-card">
|
|
208
|
+
<span class="developer-checkbox" aria-hidden="true">✓</span>
|
|
209
|
+
<span><span class="developer-environment-name">${escapeHtml(environment)}</span><span class="developer-environment-note${environment === 'prod' ? ' is-production' : ''}">${note}</span></span>
|
|
210
|
+
</span>
|
|
211
|
+
</label>`;
|
|
212
|
+
}
|
|
213
|
+
function orderedEnvironments(environments) {
|
|
214
|
+
return [...new Set(environments)].sort((left, right) => {
|
|
215
|
+
const leftPriority = ENVIRONMENT_PRIORITY[left] ?? 2;
|
|
216
|
+
const rightPriority = ENVIRONMENT_PRIORITY[right] ?? 2;
|
|
217
|
+
return leftPriority - rightPriority || left.localeCompare(right);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function environmentNote(environment) {
|
|
221
|
+
if (environment === 'dev')
|
|
222
|
+
return 'Recommended';
|
|
223
|
+
if (environment === 'prod')
|
|
224
|
+
return 'Can affect live users';
|
|
225
|
+
return 'Optional';
|
|
226
|
+
}
|
|
227
|
+
function capabilitySummary(capabilities) {
|
|
228
|
+
const actions = [];
|
|
229
|
+
if (capabilities.includes('cloud:read'))
|
|
230
|
+
actions.push('read cloud state');
|
|
231
|
+
if (capabilities.includes('deployments:write'))
|
|
232
|
+
actions.push('build and deploy apps');
|
|
233
|
+
if (capabilities.includes('deployments:rollback'))
|
|
234
|
+
actions.push('roll back deployments');
|
|
235
|
+
if (actions.length === 0)
|
|
236
|
+
return 'use its assigned capabilities';
|
|
237
|
+
if (actions.length === 1)
|
|
238
|
+
return actions[0] ?? 'use its assigned capabilities';
|
|
239
|
+
return `${actions.slice(0, -1).join(', ')} and ${actions.at(-1)}`;
|
|
52
240
|
}
|
|
53
241
|
function escapeHtml(value) {
|
|
54
242
|
return value
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"developer-grant-page.js","sourceRoot":"","sources":["../../src/oauth/developer-grant-page.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAahD,MAAM,eAAe,GAAkD;IACrE,YAAY,EAAE,gEAAgE;IAC9E,mBAAmB,EAAE,oDAAoD;IACzE,sBAAsB,EAAE,uBAAuB;CAChD,CAAC;AAEF,MAAM,
|
|
1
|
+
{"version":3,"file":"developer-grant-page.js","sourceRoot":"","sources":["../../src/oauth/developer-grant-page.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noodleseed/one",
|
|
3
|
-
"version": "0.63.
|
|
3
|
+
"version": "0.63.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Noodle CLI by Noodle Seed — author, run, and deploy declarative MCP servers. Embedding the assistant in your own web app is @noodleseed/assistant.",
|
|
6
6
|
"license": "Apache-2.0",
|