Merge 4f5a09ed89 into 318fb6efb9
				
					
				
			This commit is contained in:
		
						commit
						93e3d32a2c
					
				
							
								
								
									
										3
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -129,6 +129,7 @@ declare module '@vue/runtime-core' { | |||||||
|     MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] |     MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] | ||||||
|     MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] |     MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] | ||||||
|     NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] |     NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] | ||||||
|  |     NCheckbox: typeof import('naive-ui')['NCheckbox'] | ||||||
|     NCode: typeof import('naive-ui')['NCode'] |     NCode: typeof import('naive-ui')['NCode'] | ||||||
|     NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] |     NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] | ||||||
|     NConfigProvider: typeof import('naive-ui')['NConfigProvider'] |     NConfigProvider: typeof import('naive-ui')['NConfigProvider'] | ||||||
| @ -143,6 +144,8 @@ declare module '@vue/runtime-core' { | |||||||
|     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] |     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] | ||||||
|     NMenu: typeof import('naive-ui')['NMenu'] |     NMenu: typeof import('naive-ui')['NMenu'] | ||||||
|     NScrollbar: typeof import('naive-ui')['NScrollbar'] |     NScrollbar: typeof import('naive-ui')['NScrollbar'] | ||||||
|  |     NSpin: typeof import('naive-ui')['NSpin'] | ||||||
|  |     NTable: typeof import('naive-ui')['NTable'] | ||||||
|     NSlider: typeof import('naive-ui')['NSlider'] |     NSlider: typeof import('naive-ui')['NSlider'] | ||||||
|     NSwitch: typeof import('naive-ui')['NSwitch'] |     NSwitch: typeof import('naive-ui')['NSwitch'] | ||||||
|     NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] |     NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { describe, expect, it } from 'vitest'; | import { describe, expect, it } from 'vitest'; | ||||||
| import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation } from './chmod-calculator.service'; | import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation, computeUmaskRepresentation } from './chmod-calculator.service'; | ||||||
| 
 | 
 | ||||||
| describe('chmod-calculator', () => { | describe('chmod-calculator', () => { | ||||||
|   describe('computeChmodOctalRepresentation', () => { |   describe('computeChmodOctalRepresentation', () => { | ||||||
| @ -10,6 +10,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: true, write: true, execute: true }, |             owner: { read: true, write: true, execute: true }, | ||||||
|             group: { read: true, write: true, execute: true }, |             group: { read: true, write: true, execute: true }, | ||||||
|             public: { read: true, write: true, execute: true }, |             public: { read: true, write: true, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('777'); |       ).to.eql('777'); | ||||||
| @ -20,6 +21,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: false, write: false, execute: false }, |             owner: { read: false, write: false, execute: false }, | ||||||
|             group: { read: false, write: false, execute: false }, |             group: { read: false, write: false, execute: false }, | ||||||
|             public: { read: false, write: false, execute: false }, |             public: { read: false, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('000'); |       ).to.eql('000'); | ||||||
| @ -30,6 +32,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: false, write: true, execute: false }, |             owner: { read: false, write: true, execute: false }, | ||||||
|             group: { read: false, write: true, execute: true }, |             group: { read: false, write: true, execute: true }, | ||||||
|             public: { read: true, write: false, execute: true }, |             public: { read: true, write: false, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('235'); |       ).to.eql('235'); | ||||||
| @ -40,6 +43,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: true, write: false, execute: false }, |             owner: { read: true, write: false, execute: false }, | ||||||
|             group: { read: false, write: true, execute: false }, |             group: { read: false, write: true, execute: false }, | ||||||
|             public: { read: false, write: false, execute: true }, |             public: { read: false, write: false, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('421'); |       ).to.eql('421'); | ||||||
| @ -50,6 +54,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: false, write: false, execute: true }, |             owner: { read: false, write: false, execute: true }, | ||||||
|             group: { read: false, write: true, execute: false }, |             group: { read: false, write: true, execute: false }, | ||||||
|             public: { read: true, write: false, execute: false }, |             public: { read: true, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('124'); |       ).to.eql('124'); | ||||||
| @ -60,11 +65,57 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: false, write: true, execute: false }, |             owner: { read: false, write: true, execute: false }, | ||||||
|             group: { read: false, write: true, execute: false }, |             group: { read: false, write: true, execute: false }, | ||||||
|             public: { read: false, write: true, execute: false }, |             public: { read: false, write: true, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('222'); |       ).to.eql('222'); | ||||||
|     }); |  | ||||||
| 
 | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodOctalRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: true, execute: false }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: false, write: true, execute: false }, | ||||||
|  |             flags: { setuid: true, setgid: true, stickybit: true }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('7222'); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodOctalRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: true, execute: false }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: false, write: true, execute: false }, | ||||||
|  |             flags: { setuid: true, setgid: false, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('4222'); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodOctalRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: true, execute: false }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: false, write: true, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: true, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('2222'); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodOctalRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: true, execute: false }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: false, write: true, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: true }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('1222'); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |   describe('computeChmodSymbolicRepresentation', () => { | ||||||
|     it('get the symbolic representation from permissions', () => { |     it('get the symbolic representation from permissions', () => { | ||||||
|       expect( |       expect( | ||||||
|         computeChmodSymbolicRepresentation({ |         computeChmodSymbolicRepresentation({ | ||||||
| @ -72,6 +123,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: true, write: true, execute: true }, |             owner: { read: true, write: true, execute: true }, | ||||||
|             group: { read: true, write: true, execute: true }, |             group: { read: true, write: true, execute: true }, | ||||||
|             public: { read: true, write: true, execute: true }, |             public: { read: true, write: true, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('rwxrwxrwx'); |       ).to.eql('rwxrwxrwx'); | ||||||
| @ -82,6 +134,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: false, write: false, execute: false }, |             owner: { read: false, write: false, execute: false }, | ||||||
|             group: { read: false, write: false, execute: false }, |             group: { read: false, write: false, execute: false }, | ||||||
|             public: { read: false, write: false, execute: false }, |             public: { read: false, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('---------'); |       ).to.eql('---------'); | ||||||
| @ -92,6 +145,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: false, write: true, execute: false }, |             owner: { read: false, write: true, execute: false }, | ||||||
|             group: { read: false, write: true, execute: true }, |             group: { read: false, write: true, execute: true }, | ||||||
|             public: { read: true, write: false, execute: true }, |             public: { read: true, write: false, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('-w--wxr-x'); |       ).to.eql('-w--wxr-x'); | ||||||
| @ -102,6 +156,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: true, write: false, execute: false }, |             owner: { read: true, write: false, execute: false }, | ||||||
|             group: { read: false, write: true, execute: false }, |             group: { read: false, write: true, execute: false }, | ||||||
|             public: { read: false, write: false, execute: true }, |             public: { read: false, write: false, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('r---w---x'); |       ).to.eql('r---w---x'); | ||||||
| @ -112,6 +167,7 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: false, write: false, execute: true }, |             owner: { read: false, write: false, execute: true }, | ||||||
|             group: { read: false, write: true, execute: false }, |             group: { read: false, write: true, execute: false }, | ||||||
|             public: { read: true, write: false, execute: false }, |             public: { read: true, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('--x-w-r--'); |       ).to.eql('--x-w-r--'); | ||||||
| @ -122,9 +178,382 @@ describe('chmod-calculator', () => { | |||||||
|             owner: { read: false, write: true, execute: false }, |             owner: { read: false, write: true, execute: false }, | ||||||
|             group: { read: false, write: true, execute: false }, |             group: { read: false, write: true, execute: false }, | ||||||
|             public: { read: false, write: true, execute: false }, |             public: { read: false, write: true, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|           }, |           }, | ||||||
|         }), |         }), | ||||||
|       ).to.eql('-w--w--w-'); |       ).to.eql('-w--w--w-'); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodSymbolicRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: false, execute: true }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: true, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: true }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('--x-w-r-t'); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodSymbolicRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: false, execute: true }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: true, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: true, stickybit: true }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('--x-wsr-t'); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodSymbolicRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: false, execute: true }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: true, write: false, execute: false }, | ||||||
|  |             flags: { setuid: true, setgid: true, stickybit: true }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('--s-wsr-t'); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodSymbolicRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: true, write: false, execute: true }, | ||||||
|  |             group: { read: true, write: true, execute: false }, | ||||||
|  |             public: { read: true, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('r-xrw-r--'); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeChmodSymbolicRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: true, write: true, execute: true }, | ||||||
|  |             group: { read: true, write: true, execute: true }, | ||||||
|  |             public: { read: true, write: true, execute: true }, | ||||||
|  |             flags: { setuid: true, setgid: true, stickybit: true }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.eql('rwsrwsrwt'); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |   describe('computePermissionsFromChmodOctalRepresentation', () => { | ||||||
|  |     it('throws on invalid octal values', () => { | ||||||
|  |       expect(() => computePermissionsFromChmodOctalRepresentation('12')).to.throw(); | ||||||
|  |       expect(() => computePermissionsFromChmodOctalRepresentation('12345')).to.throw(); | ||||||
|  |       expect(() => computePermissionsFromChmodOctalRepresentation('999')).to.throw(); | ||||||
|  |       expect(() => computePermissionsFromChmodOctalRepresentation('9999')).to.throw(); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('get permissions from octal representation', () => { | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('777'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: true, write: true, execute: true }, | ||||||
|  |         group: { read: true, write: true, execute: true }, | ||||||
|  |         public: { read: true, write: true, execute: true }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('000'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: false, execute: false }, | ||||||
|  |         group: { read: false, write: false, execute: false }, | ||||||
|  |         public: { read: false, write: false, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('235'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: true }, | ||||||
|  |         public: { read: true, write: false, execute: true }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('421'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: true, write: false, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: false, execute: true }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('124'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: false, execute: true }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: true, write: false, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('222'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: true, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('7222'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: true, execute: false }, | ||||||
|  |         flags: { setuid: true, setgid: true, stickybit: true }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('4222'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: true, execute: false }, | ||||||
|  |         flags: { setuid: true, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('2222'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: true, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: true, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodOctalRepresentation('1222'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: true, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: true }, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |   describe('computePermissionsFromChmodSymbolicRepresentation', () => { | ||||||
|  |     it('throws on invalid symbolic values', () => { | ||||||
|  |       expect(() => computePermissionsFromChmodSymbolicRepresentation('rr---')).to.throw(); | ||||||
|  |       expect(() => computePermissionsFromChmodSymbolicRepresentation('rwxrwx--w')).to.throw(); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('get permissions from symbolic representation', () => { | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('dr-xr-xr-x'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: true, write: false, execute: true }, | ||||||
|  |         group: { read: true, write: false, execute: true }, | ||||||
|  |         public: { read: true, write: false, execute: true }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('-rw-r--r--'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: true, write: true, execute: false }, | ||||||
|  |         group: { read: true, write: false, execute: false }, | ||||||
|  |         public: { read: true, write: false, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('rwxrwxrwx'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: true, write: true, execute: true }, | ||||||
|  |         group: { read: true, write: true, execute: true }, | ||||||
|  |         public: { read: true, write: true, execute: true }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('---------'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: false, execute: false }, | ||||||
|  |         group: { read: false, write: false, execute: false }, | ||||||
|  |         public: { read: false, write: false, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('r---wxr-x'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: true, write: false, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: true }, | ||||||
|  |         public: { read: true, write: false, execute: true }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('r---w---x'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: true, write: false, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: false, execute: true }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('--x-w-r--'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: false, execute: true }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: true, write: false, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('-w--w--w-'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: true, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('-ws-ws-wt'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: true }, | ||||||
|  |         group: { read: false, write: true, execute: true }, | ||||||
|  |         public: { read: false, write: true, execute: true }, | ||||||
|  |         flags: { setuid: true, setgid: true, stickybit: true }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('-ws-w--w-'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: true }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: true, execute: false }, | ||||||
|  |         flags: { setuid: true, setgid: false, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('-w--ws-w-'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: true }, | ||||||
|  |         public: { read: false, write: true, execute: false }, | ||||||
|  |         flags: { setuid: false, setgid: true, stickybit: false }, | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computePermissionsFromChmodSymbolicRepresentation('-w--w--wt'), | ||||||
|  |       ).to.eql({ | ||||||
|  |         owner: { read: false, write: true, execute: false }, | ||||||
|  |         group: { read: false, write: true, execute: false }, | ||||||
|  |         public: { read: false, write: true, execute: true }, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: true }, | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   describe('computeUmaskRepresentation', () => { | ||||||
|  |     it('get the umask from permissions', () => { | ||||||
|  |       expect( | ||||||
|  |         computeUmaskRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: true, write: true, execute: true }, | ||||||
|  |             group: { read: true, write: true, execute: true }, | ||||||
|  |             public: { read: true, write: true, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.deep.eq({ | ||||||
|  |         octal: '000', | ||||||
|  |         symbolic: 'umask u=rwx,g=rwx,o=rwx', | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeUmaskRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: false, execute: false }, | ||||||
|  |             group: { read: false, write: false, execute: false }, | ||||||
|  |             public: { read: false, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.deep.eq({ | ||||||
|  |         octal: '777', | ||||||
|  |         symbolic: 'umask u=,g=,o=', | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeUmaskRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: true, execute: false }, | ||||||
|  |             group: { read: false, write: true, execute: true }, | ||||||
|  |             public: { read: true, write: false, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.deep.eq({ | ||||||
|  |         octal: '542', | ||||||
|  |         symbolic: 'umask u=w,g=wx,o=rx', | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeUmaskRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: true, write: false, execute: false }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: false, write: false, execute: true }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.deep.eq({ | ||||||
|  |         octal: '356', | ||||||
|  |         symbolic: 'umask u=r,g=w,o=x', | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeUmaskRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: false, execute: true }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: true, write: false, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.deep.eq({ | ||||||
|  |         octal: '653', | ||||||
|  |         symbolic: 'umask u=x,g=w,o=r', | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeUmaskRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: true, execute: false }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: false, write: true, execute: false }, | ||||||
|  |             flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.deep.eq({ | ||||||
|  |         octal: '555', | ||||||
|  |         symbolic: 'umask u=w,g=w,o=w', | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect( | ||||||
|  |         computeUmaskRepresentation({ | ||||||
|  |           permissions: { | ||||||
|  |             owner: { read: false, write: false, execute: true }, | ||||||
|  |             group: { read: false, write: true, execute: false }, | ||||||
|  |             public: { read: true, write: false, execute: false }, | ||||||
|  |             flags: { setuid: true, setgid: true, stickybit: true }, | ||||||
|  |           }, | ||||||
|  |         }), | ||||||
|  |       ).to.deep.eq({ | ||||||
|  |         octal: '653', | ||||||
|  |         symbolic: 'umask u=x,g=w,o=r', | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -1,15 +1,21 @@ | |||||||
| import _ from 'lodash'; | import _ from 'lodash'; | ||||||
| import type { GroupPermissions, Permissions } from './chmod-calculator.types'; | import type { GroupPermissions, Permissions, SpecialPermissions } from './chmod-calculator.types'; | ||||||
| 
 | 
 | ||||||
| export { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation }; | export { computeUmaskRepresentation, computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation }; | ||||||
| 
 | 
 | ||||||
| function computeChmodOctalRepresentation({ permissions }: { permissions: Permissions }): string { | function computeChmodOctalRepresentation({ permissions }: { permissions: Permissions }): string { | ||||||
|   const permissionValue = { read: 4, write: 2, execute: 1 }; |   const permissionValue = { read: 4, write: 2, execute: 1 }; | ||||||
|  |   const specialPermissionValue = { setuid: 4, setgid: 2, stickybit: 1 }; | ||||||
| 
 | 
 | ||||||
|   const getGroupPermissionValue = (permission: GroupPermissions) => |   const getGroupPermissionValue = (permission: GroupPermissions) => | ||||||
|     _.reduce(permission, (acc, isPermSet, key) => acc + (isPermSet ? _.get(permissionValue, key, 0) : 0), 0); |     _.reduce(permission, (acc, isPermSet, key) => acc + (isPermSet ? _.get(permissionValue, key, 0) : 0), 0); | ||||||
|  |   const getSpecialPermissionValue = (permission: SpecialPermissions) => { | ||||||
|  |     const octalValue = _.reduce(permission, (acc, isPermSet, key) => acc + (isPermSet ? _.get(specialPermissionValue, key, 0) : 0), 0); | ||||||
|  |     return octalValue > 0 ? octalValue.toString() : ''; | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   return [ |   return [ | ||||||
|  |     getSpecialPermissionValue(permissions.flags || { setuid: false, setgid: false, stickybit: false }), | ||||||
|     getGroupPermissionValue(permissions.owner), |     getGroupPermissionValue(permissions.owner), | ||||||
|     getGroupPermissionValue(permissions.group), |     getGroupPermissionValue(permissions.group), | ||||||
|     getGroupPermissionValue(permissions.public), |     getGroupPermissionValue(permissions.public), | ||||||
| @ -18,13 +24,92 @@ function computeChmodOctalRepresentation({ permissions }: { permissions: Permiss | |||||||
| 
 | 
 | ||||||
| function computeChmodSymbolicRepresentation({ permissions }: { permissions: Permissions }): string { | function computeChmodSymbolicRepresentation({ permissions }: { permissions: Permissions }): string { | ||||||
|   const permissionValue = { read: 'r', write: 'w', execute: 'x' }; |   const permissionValue = { read: 'r', write: 'w', execute: 'x' }; | ||||||
|  |   const specialFlagPermission = 'execute'; | ||||||
| 
 | 
 | ||||||
|   const getGroupPermissionValue = (permission: GroupPermissions) => |   const getGroupPermissionValue = (permission: GroupPermissions, specialFlag: null | 's' | 't') => | ||||||
|     _.reduce(permission, (acc, isPermSet, key) => acc + (isPermSet ? _.get(permissionValue, key, '') : '-'), ''); |     _.reduce(permission, (acc, isPermSet, key) => acc + ((key === specialFlagPermission ? specialFlag : undefined) | ||||||
|  |     || (isPermSet ? _.get(permissionValue, key, '') : '-')), ''); | ||||||
| 
 | 
 | ||||||
|   return [ |   return [ | ||||||
|     getGroupPermissionValue(permissions.owner), |     getGroupPermissionValue(permissions.owner, permissions.flags?.setuid ? 's' : null), | ||||||
|     getGroupPermissionValue(permissions.group), |     getGroupPermissionValue(permissions.group, permissions.flags?.setgid ? 's' : null), | ||||||
|     getGroupPermissionValue(permissions.public), |     getGroupPermissionValue(permissions.public, permissions.flags?.stickybit ? 't' : null), | ||||||
|   ].join(''); |   ].join(''); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | function computePermissionsFromChmodOctalRepresentation(octalPermissions: string): Permissions { | ||||||
|  |   const permissionValue = { read: 4, write: 2, execute: 1 }; | ||||||
|  |   const specialPermissionValue = { setuid: 4, setgid: 2, stickybit: 1 }; | ||||||
|  | 
 | ||||||
|  |   if (!octalPermissions || !octalPermissions.match(/^[0-7]{3,4}$/)) { | ||||||
|  |     throw new Error(`Invalid octal permissions (must be 3 or 4 octal digits): ${octalPermissions}`); | ||||||
|  |   } | ||||||
|  |   const fullOctalPermissions = octalPermissions.length === 3 ? `0${octalPermissions}` : octalPermissions; | ||||||
|  | 
 | ||||||
|  |   const hasSet = (position: number, flagValue: number) => (Number(fullOctalPermissions[position]) & flagValue) === flagValue; | ||||||
|  |   function computePermissionObject<T>(permissionSet: object, position: number): T { | ||||||
|  |     return _.reduce(permissionSet, (acc, flag, key) => ({ ...acc, [key]: hasSet(position, flag) }), {}) as T; | ||||||
|  |   } | ||||||
|  |   const flagsPosition = 0; | ||||||
|  |   const ownerPosition = 1; | ||||||
|  |   const groupPosition = 2; | ||||||
|  |   const publicPosition = 3; | ||||||
|  |   return { | ||||||
|  |     owner: computePermissionObject(permissionValue, ownerPosition), | ||||||
|  |     group: computePermissionObject(permissionValue, groupPosition), | ||||||
|  |     public: computePermissionObject(permissionValue, publicPosition), | ||||||
|  |     flags: computePermissionObject(specialPermissionValue, flagsPosition), | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function computePermissionsFromChmodSymbolicRepresentation(symbolicPermissions: string): Permissions { | ||||||
|  |   const formatRegex = /^[-dlbcsp]?([r-])([w-])([xs-])([r-])([w-])([xs-])([r-])([w-])([xt-])$/; | ||||||
|  |   if (!symbolicPermissions || !symbolicPermissions.match(formatRegex)) { | ||||||
|  |     throw new Error(`Invalid string permissions (must be in form 'rwxrwxrwx'): ${symbolicPermissions}`); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   const [_, rOwner, wOwner, xOwner, rGroup, wGroup, xGroup, rAll, wAll, xAll] = formatRegex.exec(symbolicPermissions) || []; | ||||||
|  |   const getOctal = (flag: string, flagLetter: string, flagValue: number) => flag === flagLetter ? flagValue : 0; | ||||||
|  |   const owner = getOctal(rOwner, 'r', 4) | ||||||
|  |   + getOctal(wOwner, 'w', 2) | ||||||
|  |   + getOctal(xOwner, 'x', 1) + getOctal(xOwner, 's', 1); | ||||||
|  |   const groups = getOctal(rGroup, 'r', 4) | ||||||
|  |   + getOctal(wGroup, 'w', 2) | ||||||
|  |   + getOctal(xGroup, 'x', 1) + getOctal(xGroup, 's', 1); | ||||||
|  |   const all = getOctal(rAll, 'r', 4) | ||||||
|  |   + getOctal(wAll, 'w', 2) | ||||||
|  |   + getOctal(xAll, 'x', 1) + getOctal(xAll, 't', 1); | ||||||
|  |   const flags = getOctal(xOwner, 's', 4) | ||||||
|  |     + getOctal(xGroup, 's', 2) | ||||||
|  |     + getOctal(xAll, 't', 1); | ||||||
|  |   const octalString = `${(flags > 0 ? flags : '')}${owner}${groups}${all}`; | ||||||
|  | 
 | ||||||
|  |   return computePermissionsFromChmodOctalRepresentation(octalString); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function computeUmaskRepresentation({ permissions }: { permissions: Permissions }): { | ||||||
|  |   octal: string | ||||||
|  |   symbolic: string | ||||||
|  | } { | ||||||
|  |   const permissionValue = { read: 'r', write: 'w', execute: 'x' }; | ||||||
|  |   const getGroupPermissionValue = (permission: GroupPermissions) => | ||||||
|  |     _.reduce(permission, (acc, isPermSet, key) => acc + ((isPermSet ? _.get(permissionValue, key, '') : '')), ''); | ||||||
|  | 
 | ||||||
|  |   const symbolic = `umask u=${getGroupPermissionValue(permissions.owner)},g=${getGroupPermissionValue(permissions.group)},o=${getGroupPermissionValue(permissions.public)}`; | ||||||
|  |   const octal = (0o777 - Number.parseInt( | ||||||
|  |     computeChmodOctalRepresentation({ | ||||||
|  |       permissions: | ||||||
|  |       { | ||||||
|  |         owner: permissions.owner, | ||||||
|  |         group: permissions.group, | ||||||
|  |         public: permissions.public, | ||||||
|  |         flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
|  |       }, | ||||||
|  |     }), 8)) | ||||||
|  |     .toString(8) | ||||||
|  |     .padStart(3, '0'); | ||||||
|  | 
 | ||||||
|  |   return { | ||||||
|  |     symbolic, octal, | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,10 +1,17 @@ | |||||||
| export type Scope = 'read' | 'write' | 'execute'; | export type Scope = 'read' | 'write' | 'execute'; | ||||||
| export type Group = 'owner' | 'group' | 'public'; | export type Group = 'owner' | 'group' | 'public'; | ||||||
|  | export type SpecialFlags = 'setuid' | 'setgid' | 'stickybit'; | ||||||
| 
 | 
 | ||||||
| export type GroupPermissions = { | export type GroupPermissions = { | ||||||
|   [k in Scope]: boolean; |   [k in Scope]: boolean; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | export type SpecialPermissions = { | ||||||
|  |   [k in SpecialFlags]: boolean; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| export type Permissions = { | export type Permissions = { | ||||||
|   [k in Group]: GroupPermissions; |   [k in Group]: GroupPermissions; | ||||||
|  | } & { | ||||||
|  |   flags: SpecialPermissions | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -2,9 +2,10 @@ | |||||||
| import { useThemeVars } from 'naive-ui'; | import { useThemeVars } from 'naive-ui'; | ||||||
| 
 | 
 | ||||||
| import InputCopyable from '../../components/InputCopyable.vue'; | import InputCopyable from '../../components/InputCopyable.vue'; | ||||||
| import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation } from './chmod-calculator.service'; | import { computeChmodOctalRepresentation, computeChmodSymbolicRepresentation, computePermissionsFromChmodOctalRepresentation, computePermissionsFromChmodSymbolicRepresentation, computeUmaskRepresentation } from './chmod-calculator.service'; | ||||||
| 
 | 
 | ||||||
| import type { Group, Scope } from './chmod-calculator.types'; | import type { Group, Scope } from './chmod-calculator.types'; | ||||||
|  | import { useValidation } from '@/composable/validation'; | ||||||
| 
 | 
 | ||||||
| const themeVars = useThemeVars(); | const themeVars = useThemeVars(); | ||||||
| 
 | 
 | ||||||
| @ -19,14 +20,92 @@ const permissions = ref({ | |||||||
|   owner: { read: false, write: false, execute: false }, |   owner: { read: false, write: false, execute: false }, | ||||||
|   group: { read: false, write: false, execute: false }, |   group: { read: false, write: false, execute: false }, | ||||||
|   public: { read: false, write: false, execute: false }, |   public: { read: false, write: false, execute: false }, | ||||||
|  |   flags: { setuid: false, setgid: false, stickybit: false }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | const octalPermissionsInput = ref('000'); | ||||||
|  | const octalPermissionsInputValidation = useValidation({ | ||||||
|  |   source: octalPermissionsInput, | ||||||
|  |   rules: [ | ||||||
|  |     { | ||||||
|  |       message: 'Invalid octal permission string', | ||||||
|  |       validator: (value) => { | ||||||
|  |         try { | ||||||
|  |           computePermissionsFromChmodOctalRepresentation(value.trim()); | ||||||
|  |           return true; | ||||||
|  |         } | ||||||
|  |         catch { | ||||||
|  |           return false; | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  | }); | ||||||
|  | watch( | ||||||
|  |   octalPermissionsInput, | ||||||
|  |   (newPermissions) => { | ||||||
|  |     if (!octalPermissionsInputValidation.isValid) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     permissions.value = computePermissionsFromChmodOctalRepresentation(newPermissions.trim()); | ||||||
|  |   }, | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | const symbolicPermissionsInput = ref('---------'); | ||||||
|  | const symbolicPermissionsInputValidation = useValidation({ | ||||||
|  |   source: symbolicPermissionsInput, | ||||||
|  |   rules: [ | ||||||
|  |     { | ||||||
|  |       message: 'Invalid symbolic permission string', | ||||||
|  |       validator: (value) => { | ||||||
|  |         try { | ||||||
|  |           computePermissionsFromChmodSymbolicRepresentation(value.trim()); | ||||||
|  |           return true; | ||||||
|  |         } | ||||||
|  |         catch { | ||||||
|  |           return false; | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  | }); | ||||||
|  | watch( | ||||||
|  |   symbolicPermissionsInput, | ||||||
|  |   (newPermissions) => { | ||||||
|  |     if (!symbolicPermissionsInputValidation.isValid) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     permissions.value = computePermissionsFromChmodSymbolicRepresentation(newPermissions.trim()); | ||||||
|  |   }, | ||||||
|  | ); | ||||||
|  | 
 | ||||||
| const octal = computed(() => computeChmodOctalRepresentation({ permissions: permissions.value })); | const octal = computed(() => computeChmodOctalRepresentation({ permissions: permissions.value })); | ||||||
| const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions: permissions.value })); | const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions: permissions.value })); | ||||||
|  | const umask = computed(() => computeUmaskRepresentation({ permissions: permissions.value })); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
|   <div> |   <div> | ||||||
|  |     <c-input-text | ||||||
|  |       v-model:value="octalPermissionsInput" | ||||||
|  |       placeholder="Put your octal permissions here..." | ||||||
|  |       label="Copy your octal permissions" | ||||||
|  |       :validation="octalPermissionsInputValidation" | ||||||
|  |       mb-2 | ||||||
|  |     /> | ||||||
|  | 
 | ||||||
|  |     <n-divider /> | ||||||
|  | 
 | ||||||
|  |     <c-input-text | ||||||
|  |       v-model:value="symbolicPermissionsInput" | ||||||
|  |       placeholder="Put your symbolic permissions here..." | ||||||
|  |       label="Copy your symbolic permissions" | ||||||
|  |       :validation="symbolicPermissionsInputValidation" | ||||||
|  |       mb-2 | ||||||
|  |     /> | ||||||
|  | 
 | ||||||
|  |     <n-divider /> | ||||||
|  | 
 | ||||||
|     <n-table :bordered="false" :bottom-bordered="false" single-column class="permission-table"> |     <n-table :bordered="false" :bottom-bordered="false" single-column class="permission-table"> | ||||||
|       <thead> |       <thead> | ||||||
|         <tr> |         <tr> | ||||||
| @ -52,6 +131,20 @@ const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions | |||||||
|             <n-checkbox v-model:checked="permissions[group][scope]" size="large" /> |             <n-checkbox v-model:checked="permissions[group][scope]" size="large" /> | ||||||
|           </td> |           </td> | ||||||
|         </tr> |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td class="line-header"> | ||||||
|  |             Flags | ||||||
|  |           </td> | ||||||
|  |           <td class="text-center"> | ||||||
|  |             <n-checkbox v-model:checked="permissions.flags.setuid" size="large" /> | ||||||
|  |           </td> | ||||||
|  |           <td class="text-center"> | ||||||
|  |             <n-checkbox v-model:checked="permissions.flags.setgid" size="large" /> | ||||||
|  |           </td> | ||||||
|  |           <td class="text-center"> | ||||||
|  |             <n-checkbox v-model:checked="permissions.flags.stickybit" size="large" /> | ||||||
|  |           </td> | ||||||
|  |         </tr> | ||||||
|       </tbody> |       </tbody> | ||||||
|     </n-table> |     </n-table> | ||||||
| 
 | 
 | ||||||
| @ -63,6 +156,11 @@ const symbolic = computed(() => computeChmodSymbolicRepresentation({ permissions | |||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <InputCopyable :value="`chmod ${octal} path`" readonly /> |     <InputCopyable :value="`chmod ${octal} path`" readonly /> | ||||||
|  | 
 | ||||||
|  |     <c-card title="Umask"> | ||||||
|  |       <InputCopyable :value="umask.octal" readonly /> | ||||||
|  |       <InputCopyable :value="umask.symbolic" readonly /> | ||||||
|  |     </c-card> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,11 +1,10 @@ | |||||||
| import { FileInvoice } from '@vicons/tabler'; | import { FileInvoice } from '@vicons/tabler'; | ||||||
| import { defineTool } from '../tool'; | import { defineTool } from '../tool'; | ||||||
| import { translate } from '@/plugins/i18n.plugin'; |  | ||||||
| 
 | 
 | ||||||
| export const tool = defineTool({ | export const tool = defineTool({ | ||||||
|   name: translate('tools.chmod-calculator.title'), |   name: 'Chmod calculator', | ||||||
|   path: '/chmod-calculator', |   path: '/chmod-calculator', | ||||||
|   description: translate('tools.chmod-calculator.description'), |   description: 'Compute your chmod permissions and commands with this online chmod calculator.', | ||||||
|   keywords: [ |   keywords: [ | ||||||
|     'chmod', |     'chmod', | ||||||
|     'calculator', |     'calculator', | ||||||
| @ -17,6 +16,7 @@ export const tool = defineTool({ | |||||||
|     'recursive', |     'recursive', | ||||||
|     'generator', |     'generator', | ||||||
|     'octal', |     'octal', | ||||||
|  |     'umask', | ||||||
|   ], |   ], | ||||||
|   component: () => import('./chmod-calculator.vue'), |   component: () => import('./chmod-calculator.vue'), | ||||||
|   icon: FileInvoice, |   icon: FileInvoice, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user