UNPKG

@yuebai008/cli

Version:

Command line interface for rapid qg-minigame development

6 lines 15.8 kB
import*as Common from"../../core/common/common.js";import*as Host from"../../core/host/host.js";import*as i18n from"../../core/i18n/i18n.js";import*as SDK from"../../core/sdk/sdk.js";import*as DataGrid from"../../ui/legacy/components/data_grid/data_grid.js";import*as UI from"../../ui/legacy/legacy.js";import webauthnPaneStyles from"./webauthnPane.css.js";const UIStrings={export:"Export",remove:"Remove",noCredentialsTryCallingSFromYour:"No credentials. Try calling {PH1} from your website.",enableVirtualAuthenticator:"Enable virtual authenticator environment",id:"ID",isResident:"Is Resident",rpId:"RP ID",userHandle:"User Handle",signCount:"Signature Count",actions:"Actions",credentials:"Credentials",useWebauthnForPhishingresistant:"Use WebAuthn for phishing-resistant authentication",learnMore:"Learn more",newAuthenticator:"New authenticator",protocol:"Protocol",transport:"Transport",supportsResidentKeys:"Supports resident keys",supportsLargeBlob:"Supports large blob",add:"Add",addAuthenticator:"Add authenticator",active:"Active",editName:"Edit name",saveName:"Save name",authenticatorS:"Authenticator {PH1}",privateKeypem:"Private key.pem",uuid:"UUID",supportsUserVerification:"Supports user verification",yes:"Yes",no:"No",setSAsTheActiveAuthenticator:"Set {PH1} as the active authenticator"},str_=i18n.i18n.registerUIStrings("panels/webauthn/WebauthnPane.ts",UIStrings),i18nString=i18n.i18n.getLocalizedString.bind(void 0,str_);class DataGridNode extends DataGrid.DataGrid.DataGridNode{credential;constructor(t){super(t),this.credential=t}nodeSelfHeight(){return 24}createCell(t){const e=super.createCell(t);if(UI.Tooltip.Tooltip.install(e,e.textContent||""),"actions"!==t)return e;const i=UI.UIUtils.createTextButton(i18nString(UIStrings.export),(()=>{this.dataGrid&&this.dataGrid.dispatchEventToListeners("ExportCredential",this.credential)}));e.appendChild(i);const a=UI.UIUtils.createTextButton(i18nString(UIStrings.remove),(()=>{this.dataGrid&&this.dataGrid.dispatchEventToListeners("RemoveCredential",this.credential)}));return e.appendChild(a),e}}class WebauthnDataGridBase extends DataGrid.DataGrid.DataGridImpl{}class WebauthnDataGrid extends(Common.ObjectWrapper.eventMixin(WebauthnDataGridBase)){}class EmptyDataGridNode extends DataGrid.DataGrid.DataGridNode{createCells(t){t.removeChildren();const e=this.createTDWithClass(DataGrid.DataGrid.Align.Center);this.dataGrid&&(e.colSpan=this.dataGrid.visibleColumnsArray.length);const i=document.createElement("span",{is:"source-code"});i.textContent="navigator.credentials.create()",i.classList.add("code");const a=i18n.i18n.getFormatLocalizedString(str_,UIStrings.noCredentialsTryCallingSFromYour,{PH1:i});e.appendChild(a),t.appendChild(e)}}let webauthnPaneImplInstance;const PRIVATE_NAME="PRIVATE",PRIVATE_KEY_HEADER="-----BEGIN PRIVATE KEY-----\n",PRIVATE_KEY_FOOTER="-----END PRIVATE KEY-----",PROTOCOL_AUTHENTICATOR_VALUES={Ctap2:"ctap2",U2f:"u2f"};export class WebauthnPaneImpl extends UI.Widget.VBox{#t=null;#e=!1;dataGrids=new Map;#i;#a;#n;#o;#r;#s;#c;#l;#d;#h;#u;#b;residentKeyCheckbox;#p;#C;#g;largeBlobCheckbox;addAuthenticatorButton;#m;constructor(){super(!0),SDK.TargetManager.TargetManager.instance().observeModels(SDK.WebAuthnModel.WebAuthnModel,this,{scoped:!0}),this.contentElement.classList.add("webauthn-pane"),this.#a=Common.Settings.Settings.instance().createSetting("webauthnAuthenticators",[]),this.#S(),this.#o=this.contentElement.createChild("div","authenticators-view"),this.#v(),this.#I(!1)}static instance(t){return webauthnPaneImplInstance&&!t?.forceNew||(webauthnPaneImplInstance=new WebauthnPaneImpl),webauthnPaneImplInstance}modelAdded(t){t.target()===t.target().outermostTarget()&&(this.#n=t)}modelRemoved(t){t.target()===t.target().outermostTarget()&&(this.#n=void 0)}async#A(){let t=null;const e=this.#a.get();for(const i of e){if(!this.#n)continue;const e=await this.#n.addAuthenticator(i);this.#U(e,i),i.authenticatorId=e,i.active&&(t=e)}this.#a.set(e),t&&this.#x(t)}async ownerViewDisposed(){this.#i&&this.#i.setChecked(!1),await this.#k(!1)}#S(){this.#r=this.contentElement.createChild("div","webauthn-toolbar-container"),this.#s=new UI.Toolbar.Toolbar("webauthn-toolbar",this.#r);const t=i18nString(UIStrings.enableVirtualAuthenticator);this.#i=new UI.Toolbar.ToolbarCheckbox(t,t,this.#E.bind(this)),this.#s.appendToolbarItem(this.#i)}#w(t){const e=[{id:"credentialId",title:i18nString(UIStrings.id),longText:!0,weight:24},{id:"isResidentCredential",title:i18nString(UIStrings.isResident),dataType:DataGrid.DataGrid.DataType.Boolean,weight:10},{id:"rpId",title:i18nString(UIStrings.rpId)},{id:"userHandle",title:i18nString(UIStrings.userHandle)},{id:"signCount",title:i18nString(UIStrings.signCount)},{id:"actions",title:i18nString(UIStrings.actions)}],i={displayName:i18nString(UIStrings.credentials),columns:e,editCallback:void 0,deleteCallback:void 0,refreshCallback:void 0},a=new WebauthnDataGrid(i);return a.renderInline(),a.setStriped(!0),a.addEventListener("ExportCredential",this.#f,this),a.addEventListener("RemoveCredential",this.#L.bind(this,t)),a.rootNode().appendChild(new EmptyDataGridNode),this.dataGrids.set(t,a),a}#f({data:t}){this.#T(t)}#L(t,{data:e}){this.#y(t,e.credentialId)}#V(t,{data:e}){const i=this.dataGrids.get(t);if(!i)return;const a=i.rootNode().children.find((t=>!Object.keys(t.data).length));a&&i.rootNode().removeChild(a);const n=new DataGridNode(e.credential);i.rootNode().appendChild(n)}#B(t,{data:e}){const i=this.dataGrids.get(t);if(!i)return;const a=i.rootNode().children.find((t=>t.data?.credentialId===e.credential.credentialId));a&&(a.data=e.credential)}async#k(t){await this.#m,this.#m=new Promise((async e=>{t&&!this.#e&&(Host.userMetrics.actionTaken(Host.UserMetrics.Action.VirtualAuthenticatorEnvironmentEnabled),this.#e=!0),this.#n&&await this.#n.setVirtualAuthEnvEnabled(t),t?await this.#A():this.#G(),this.#I(t),this.#m=void 0,e()}))}#I(t){this.contentElement.classList.toggle("enabled",t)}#G(){this.#o.innerHTML="";for(const t of this.dataGrids.values())t.asWidget().detach();this.dataGrids.clear()}#E(t){this.#k(t.target.checked)}#N(t){if(!this.#u)return;const e=this.#u.value;this.#u.removeChildren();for(const e of t)this.#u.appendChild(new Option(e,e));this.#u.value=e,this.#u.value||(this.#u.selectedIndex=0)}#R(){this.#h&&this.residentKeyCheckbox&&this.#C&&this.largeBlobCheckbox&&("ctap2"===this.#h.value?(this.residentKeyCheckbox.disabled=!1,this.#C.disabled=!1,this.largeBlobCheckbox.disabled=!this.residentKeyCheckbox.checked,this.largeBlobCheckbox.disabled&&(this.largeBlobCheckbox.checked=!1),this.#N(["usb","ble","nfc","internal"])):(this.residentKeyCheckbox.checked=!1,this.residentKeyCheckbox.disabled=!0,this.#C.checked=!1,this.#C.disabled=!0,this.largeBlobCheckbox.checked=!1,this.largeBlobCheckbox.disabled=!0,this.#N(["usb","ble","nfc"])))}#v(){this.#c=this.contentElement.createChild("div","learn-more"),this.#c.appendChild(UI.Fragment.html` <div> ${i18nString(UIStrings.useWebauthnForPhishingresistant)}<br /><br /> ${UI.XLink.XLink.create("https://developers.google.com/web/updates/2018/05/webauthn",i18nString(UIStrings.learnMore))} </div> `),this.#l=this.contentElement.createChild("div","new-authenticator-container");const t=UI.UIUtils.createLabel(i18nString(UIStrings.newAuthenticator),"new-authenticator-title");this.#l.appendChild(t),this.#d=this.#l.createChild("div","new-authenticator-form");const e=this.#d.createChild("div","authenticator-option"),i=this.#d.createChild("div","authenticator-option"),a=this.#d.createChild("div","authenticator-option"),n=this.#d.createChild("div","authenticator-option"),o=this.#d.createChild("div","authenticator-option"),r=this.#d.createChild("div","authenticator-option"),s=UI.UIUtils.createLabel(i18nString(UIStrings.protocol),"authenticator-option-label");e.appendChild(s),this.#h=e.createChild("select","chrome-select"),UI.ARIAUtils.bindLabelToControl(s,this.#h),Object.values(PROTOCOL_AUTHENTICATOR_VALUES).sort().forEach((t=>{this.#h&&this.#h.appendChild(new Option(t,t))})),this.#h&&(this.#h.value="ctap2");const c=UI.UIUtils.createLabel(i18nString(UIStrings.transport),"authenticator-option-label");i.appendChild(c),this.#u=i.createChild("select","chrome-select"),UI.ARIAUtils.bindLabelToControl(c,this.#u),this.#b=UI.UIUtils.CheckboxLabel.create(i18nString(UIStrings.supportsResidentKeys),!1),this.#b.textElement.classList.add("authenticator-option-label"),a.appendChild(this.#b.textElement),this.residentKeyCheckbox=this.#b.checkboxElement,this.residentKeyCheckbox.checked=!1,this.residentKeyCheckbox.classList.add("authenticator-option-checkbox"),a.appendChild(this.#b),this.#p=UI.UIUtils.CheckboxLabel.create(i18nString(UIStrings.supportsUserVerification),!1),this.#p.textElement.classList.add("authenticator-option-label"),n.appendChild(this.#p.textElement),this.#C=this.#p.checkboxElement,this.#C.checked=!1,this.#C.classList.add("authenticator-option-checkbox"),n.appendChild(this.#p),this.#g=UI.UIUtils.CheckboxLabel.create(i18nString(UIStrings.supportsLargeBlob),!1),this.#g.textElement.classList.add("authenticator-option-label"),o.appendChild(this.#g.textElement),this.largeBlobCheckbox=this.#g.checkboxElement,this.largeBlobCheckbox.checked=!1,this.largeBlobCheckbox.classList.add("authenticator-option-checkbox"),this.largeBlobCheckbox.name="large-blob-checkbox",o.appendChild(this.#g),this.addAuthenticatorButton=UI.UIUtils.createTextButton(i18nString(UIStrings.add),this.#D.bind(this),""),r.createChild("div","authenticator-option-label"),r.appendChild(this.addAuthenticatorButton);const l=UI.UIUtils.createLabel(i18nString(UIStrings.addAuthenticator),"");UI.ARIAUtils.bindLabelToControl(l,this.addAuthenticatorButton),this.#R(),this.#h&&this.#h.addEventListener("change",this.#R.bind(this)),this.residentKeyCheckbox&&this.residentKeyCheckbox.addEventListener("change",this.#R.bind(this))}async#D(){const t=this.#K();if(this.#n){const e=await this.#n.addAuthenticator(t),i=this.#a.get();i.push({authenticatorId:e,active:!0,...t}),this.#a.set(i.map((t=>({...t,active:t.authenticatorId===e}))));const a=await this.#U(e,t),n=window.matchMedia("(prefers-reduced-motion: reduce)").matches;a.scrollIntoView({block:"start",behavior:n?"auto":"smooth"})}}async#U(t,e){const i=document.createElement("div");i.classList.add("authenticator-section"),i.setAttribute("data-authenticator-id",t),this.#o.appendChild(i);const a=i.createChild("div","authenticator-section-header"),n=a.createChild("div","authenticator-section-title");UI.ARIAUtils.markAsHeading(n,2),await this.#P();const o=a.createChild("div","active-button-container"),r=UI.UIUtils.createRadioLabel(`active-authenticator-${t}`,i18nString(UIStrings.active));r.radioElement.addEventListener("click",this.#x.bind(this,t)),o.appendChild(r),r.radioElement.checked=!0,this.#t=t;const s=a.createChild("button","text-button");s.textContent=i18nString(UIStrings.remove),s.addEventListener("click",this.#O.bind(this,t));const c=new UI.Toolbar.Toolbar("edit-name-toolbar",n),l=new UI.Toolbar.ToolbarButton(i18nString(UIStrings.editName),"edit"),d=new UI.Toolbar.ToolbarButton(i18nString(UIStrings.saveName),"checkmark");d.setVisible(!1);const h=n.createChild("input","authenticator-name-field");h.disabled=!0;const u=t.slice(-5);h.value=i18nString(UIStrings.authenticatorS,{PH1:u}),this.#F(r,h.value),l.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,(()=>this.#H(n,h,l,d))),d.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,(()=>this.#_(n,h,l,d,r))),h.addEventListener("focusout",(()=>this.#_(n,h,l,d,r))),h.addEventListener("keydown",(t=>{"Enter"===t.key&&this.#_(n,h,l,d,r)})),c.appendToolbarItem(l),c.appendToolbarItem(d),this.#W(i,t,e);const b=document.createElement("div");b.classList.add("credentials-title"),b.textContent=i18nString(UIStrings.credentials),i.appendChild(b);return this.#w(t).asWidget().show(i),this.#n&&(this.#n.addEventListener("CredentialAdded",this.#V.bind(this,t)),this.#n.addEventListener("CredentialAsserted",this.#B.bind(this,t))),i}#T(t){let e=PRIVATE_KEY_HEADER;for(let i=0;i<t.privateKey.length;i+=64)e+=t.privateKey.substring(i,i+64)+"\n";e+=PRIVATE_KEY_FOOTER;const i=document.createElement("a");i.download=i18nString(UIStrings.privateKeypem),i.href="data:application/x-pem-file,"+encodeURIComponent(e),i.click()}async#y(t,e){const i=this.dataGrids.get(t);i&&(i.rootNode().children.find((t=>t.data.credentialId===e)).remove(),i.rootNode().children.length||i.rootNode().appendChild(new EmptyDataGridNode),this.#n&&await this.#n.removeCredential(t,e))}#W(t,e,i){const a=t.createChild("div","authenticator-fields"),n=a.createChild("div","authenticator-field"),o=a.createChild("div","authenticator-field"),r=a.createChild("div","authenticator-field"),s=a.createChild("div","authenticator-field"),c=a.createChild("div","authenticator-field"),l=a.createChild("div","authenticator-field");n.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.uuid),"authenticator-option-label")),o.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.protocol),"authenticator-option-label")),r.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.transport),"authenticator-option-label")),s.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.supportsResidentKeys),"authenticator-option-label")),c.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.supportsLargeBlob),"authenticator-option-label")),l.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.supportsUserVerification),"authenticator-option-label")),n.createChild("div","authenticator-field-value").textContent=e,o.createChild("div","authenticator-field-value").textContent=i.protocol,r.createChild("div","authenticator-field-value").textContent=i.transport,s.createChild("div","authenticator-field-value").textContent=i.hasResidentKey?i18nString(UIStrings.yes):i18nString(UIStrings.no),c.createChild("div","authenticator-field-value").textContent=i.hasLargeBlob?i18nString(UIStrings.yes):i18nString(UIStrings.no),l.createChild("div","authenticator-field-value").textContent=i.hasUserVerification?i18nString(UIStrings.yes):i18nString(UIStrings.no)}#H(t,e,i,a){e.disabled=!1,t.classList.add("editing-name"),e.focus(),a.setVisible(!0),i.setVisible(!1)}#_(t,e,i,a,n){e.disabled=!0,t.classList.remove("editing-name"),i.setVisible(!0),a.setVisible(!1),this.#F(n,e.value)}#F(t,e){UI.Tooltip.Tooltip.install(t.radioElement,i18nString(UIStrings.setSAsTheActiveAuthenticator,{PH1:e}))}#O(t){if(this.#o){const e=this.#o.querySelector(`[data-authenticator-id=${CSS.escape(t)}]`);e&&e.remove()}const e=this.dataGrids.get(t);e&&(e.asWidget().detach(),this.dataGrids.delete(t)),this.#n&&this.#n.removeAuthenticator(t);const i=this.#a.get().filter((e=>e.authenticatorId!==t));if(this.#a.set(i),this.#t===t){const t=Array.from(this.dataGrids.keys());t.length?this.#x(t[0]):this.#t=null}}#K(){if(!(this.#h&&this.#u&&this.residentKeyCheckbox&&this.#C&&this.largeBlobCheckbox))throw new Error("Unable to create options from current inputs");return{protocol:this.#h.options[this.#h.selectedIndex].value,ctap2Version:"ctap2_1",transport:this.#u.options[this.#u.selectedIndex].value,hasResidentKey:this.residentKeyCheckbox.checked,hasUserVerification:this.#C.checked,hasLargeBlob:this.largeBlobCheckbox.checked,automaticPresenceSimulation:!0,isUserVerified:!0}}async#x(t){await this.#P(),this.#n&&await this.#n.setAutomaticPresenceSimulation(t,!0),this.#t=t;const e=this.#a.get().map((e=>({...e,active:e.authenticatorId===t})));this.#a.set(e),this.#M()}#M(){const t=this.#o.getElementsByClassName("authenticator-section");Array.from(t).forEach((t=>{const e=t.querySelector("input.dt-radio-button");e&&(e.checked=t.dataset.authenticatorId===this.#t)}))}async#P(){this.#t&&this.#n&&await this.#n.setAutomaticPresenceSimulation(this.#t,!1),this.#t=null,this.#M()}wasShown(){super.wasShown(),this.registerCSSFiles([webauthnPaneStyles])}}