mirror of
				https://github.com/gristlabs/grist-core.git
				synced 2025-06-13 20:53:59 +00:00 
			
		
		
		
	Displays the current authentication mechanism in the admin panel (#981)
* Adds authentication mechanism to admin panel Adds field to the "Security settings" admin display, showing the currently configured authentication mechanism. * Adds 14px margin to admin panel names
This commit is contained in:
		
							parent
							
								
									d8f4e075fe
								
							
						
					
					
						commit
						b4acb157f8
					
				| @ -105,6 +105,13 @@ export class AdminPanel extends Disposable { | ||||
|           value: this._buildSandboxingDisplay(owner), | ||||
|           expandedContent: this._buildSandboxingNotice(), | ||||
|         }), | ||||
|         dom.create(AdminSectionItem, { | ||||
|           id: 'authentication', | ||||
|           name: t('Authentication'), | ||||
|           description: t('Current authentication method'), | ||||
|           value: this._buildAuthenticationDisplay(owner), | ||||
|           expandedContent: this._buildAuthenticationNotice(owner), | ||||
|         }) | ||||
|       ]), | ||||
| 
 | ||||
|       dom.create(AdminSection, t('Version'), [ | ||||
| @ -156,6 +163,37 @@ isolated from other documents and isolated from the network.'), | ||||
|     ]; | ||||
|   } | ||||
| 
 | ||||
|   private _buildAuthenticationDisplay(owner: IDisposableOwner) { | ||||
|     return dom.domComputed( | ||||
|       use => { | ||||
|         const req = this._checks.requestCheckById(use, 'authentication'); | ||||
|         const result = req ? use(req.result) : undefined; | ||||
|         if (!result) { | ||||
|           return cssValueLabel(cssErrorText('unavailable')); | ||||
|         } | ||||
| 
 | ||||
|         const { success, details } = result; | ||||
|         const loginSystemId = details?.loginSystemId; | ||||
| 
 | ||||
|         if (!success || !loginSystemId) { | ||||
|           return cssValueLabel(cssErrorText('auth error')); | ||||
|         } | ||||
| 
 | ||||
|         if (loginSystemId === 'no-logins') { | ||||
|           return cssValueLabel(cssDangerText('no authentication')); | ||||
|         } | ||||
| 
 | ||||
|         return cssValueLabel(cssHappyText(loginSystemId)); | ||||
|       } | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   private _buildAuthenticationNotice(owner: IDisposableOwner) { | ||||
|     return t('Grist allows different types of authentication to be configured, including SAML and OIDC. \ | ||||
|     We recommend enabling one of these if Grist is accessible over the network or being made available \ | ||||
|     to multiple people.'); | ||||
|   } | ||||
| 
 | ||||
|   private _buildUpdates(owner: MultiHolder) { | ||||
|     // We can be in those states:
 | ||||
|     enum State { | ||||
| @ -446,6 +484,10 @@ const cssErrorText = styled('span', ` | ||||
|   color: ${theme.errorText}; | ||||
| `);
 | ||||
| 
 | ||||
| export const cssDangerText = styled('div', ` | ||||
|   color: ${theme.dangerText}; | ||||
| `);
 | ||||
| 
 | ||||
| const cssHappyText = styled('span', ` | ||||
|   color: ${theme.controlFg}; | ||||
| `);
 | ||||
|  | ||||
| @ -124,6 +124,7 @@ const cssItemName = styled('div', ` | ||||
|   font-weight: bold; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   margin-right: 14px; | ||||
|   font-size: ${vars.largeFontSize}; | ||||
|   padding-left: 24px; | ||||
|   &-prefixed { | ||||
|  | ||||
| @ -6,7 +6,8 @@ export type BootProbeIds = | ||||
|     'reachable' | | ||||
|     'host-header' | | ||||
|     'sandboxing' | | ||||
|     'system-user' | ||||
|     'system-user' | | ||||
|     'authentication' | ||||
| ; | ||||
| 
 | ||||
| export interface BootProbeResult { | ||||
|  | ||||
| @ -58,6 +58,7 @@ export class BootProbes { | ||||
|     this._probes.push(_bootProbe); | ||||
|     this._probes.push(_hostHeaderProbe); | ||||
|     this._probes.push(_sandboxingProbe); | ||||
|     this._probes.push(_authenticationProbe); | ||||
|     this._probeById = new Map(this._probes.map(p => [p.id, p])); | ||||
|   } | ||||
| } | ||||
| @ -202,3 +203,17 @@ const _sandboxingProbe: Probe = { | ||||
|     }; | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| const _authenticationProbe: Probe = { | ||||
|   id: 'authentication', | ||||
|   name: 'Authentication system', | ||||
|   apply: async(server, req) => { | ||||
|     const loginSystemId = server.getInfo('loginMiddlewareComment'); | ||||
|     return { | ||||
|       success: loginSystemId != undefined, | ||||
|       details: { | ||||
|         loginSystemId, | ||||
|       } | ||||
|     }; | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| @ -1426,6 +1426,11 @@ export class FlexServer implements GristServer { | ||||
|     return this._sandboxInfo; | ||||
|   } | ||||
| 
 | ||||
|   public getInfo(key: string): any { | ||||
|     const infoPair = this.info.find(([keyToCheck]) => key === keyToCheck); | ||||
|     return infoPair?.[1]; | ||||
|   } | ||||
| 
 | ||||
|   public disableExternalStorage() { | ||||
|     if (this.deps.has('doc')) { | ||||
|       throw new Error('disableExternalStorage called too late'); | ||||
|  | ||||
| @ -67,6 +67,7 @@ export interface GristServer { | ||||
|   getBundledWidgets(): ICustomWidget[]; | ||||
|   hasBoot(): boolean; | ||||
|   getSandboxInfo(): SandboxInfo|undefined; | ||||
|   getInfo(key: string): any; | ||||
| } | ||||
| 
 | ||||
| export interface GristLoginSystem { | ||||
| @ -159,6 +160,7 @@ export function createDummyGristServer(): GristServer { | ||||
|     getBundledWidgets() { return []; }, | ||||
|     hasBoot() { return false; }, | ||||
|     getSandboxInfo() { return undefined; }, | ||||
|     getInfo(key: string) { return undefined; } | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user