UNPKG

@energica-city/shared-amplify-utils

Version:

Shared utilities for AWS Amplify projects

362 lines 41.7 kB
import { describe, it, expect } from 'vitest'; import { sanitizeObject } from './sanitization'; describe('Sanitization Utility', () => { describe('sanitizeObject', () => { describe('primitive values', () => { it('should return primitive values unchanged', () => { expect(sanitizeObject('test string')).toBe('test string'); expect(sanitizeObject(123)).toBe(123); expect(sanitizeObject(true)).toBe(true); expect(sanitizeObject(false)).toBe(false); }); it('should handle null and undefined', () => { expect(sanitizeObject(null)).toBe(null); expect(sanitizeObject(undefined)).toBe(undefined); }); }); describe('sensitive field detection', () => { it('should redact password fields', () => { const input = { username: 'testuser', password: 'secret123', email: 'test@example.com', }; const expected = { username: 'testuser', password: '[REDACTED]', email: 'test@example.com', }; expect(sanitizeObject(input)).toEqual(expected); }); it('should redact token fields', () => { const input = { accessToken: 'abc123', refreshToken: 'def456', userToken: 'ghi789', }; const expected = { accessToken: '[REDACTED]', refreshToken: '[REDACTED]', userToken: '[REDACTED]', }; expect(sanitizeObject(input)).toEqual(expected); }); it('should redact secret fields', () => { const input = { apiSecret: 'secret123', clientSecret: 'secret456', secretKey: 'secret789', }; const expected = { apiSecret: '[REDACTED]', clientSecret: '[REDACTED]', secretKey: '[REDACTED]', }; expect(sanitizeObject(input)).toEqual(expected); }); it('should redact key fields', () => { const input = { apiKey: 'key123', privateKey: 'key456', encryptionKey: 'key789', }; const expected = { apiKey: '[REDACTED]', privateKey: '[REDACTED]', encryptionKey: '[REDACTED]', }; expect(sanitizeObject(input)).toEqual(expected); }); it('should redact auth fields', () => { const input = { authorization: 'Bearer token123', authHeader: 'Basic dXNlcjpwYXNz', authToken: 'token456', }; const expected = { authorization: '[REDACTED]', authHeader: '[REDACTED]', authToken: '[REDACTED]', }; expect(sanitizeObject(input)).toEqual(expected); }); it('should handle case-insensitive field detection', () => { const input = { PASSWORD: 'secret123', AccessToken: 'token123', API_SECRET: 'secret456', private_key: 'key123', Authorization: 'Bearer token', }; const expected = { PASSWORD: '[REDACTED]', AccessToken: '[REDACTED]', API_SECRET: '[REDACTED]', private_key: '[REDACTED]', Authorization: '[REDACTED]', }; expect(sanitizeObject(input)).toEqual(expected); }); }); describe('excludeFields configuration', () => { it('should redact explicitly excluded fields', () => { const input = { username: 'testuser', email: 'test@example.com', phone: '123-456-7890', }; const config = { excludeFields: ['email', 'phone'], }; const expected = { username: 'testuser', email: '[REDACTED]', phone: '[REDACTED]', }; expect(sanitizeObject(input, config)).toEqual(expected); }); it('should combine excludeFields with sensitive field detection', () => { const input = { username: 'testuser', password: 'secret123', email: 'test@example.com', phone: '123-456-7890', }; const config = { excludeFields: ['email'], }; const expected = { username: 'testuser', password: '[REDACTED]', email: '[REDACTED]', phone: '123-456-7890', }; expect(sanitizeObject(input, config)).toEqual(expected); }); }); describe('maxDepth configuration', () => { it('should respect maxDepth limit', () => { const input = { level1: { level2: { level3: { level4: 'too deep', }, }, }, }; const config = { maxDepth: 2, }; const expected = { level1: { level2: '[Object: max depth reached]', }, }; expect(sanitizeObject(input, config)).toEqual(expected); }); it('should use default maxDepth of 3', () => { const input = { level1: { level2: { level3: { level4: 'too deep', }, }, }, }; const expected = { level1: { level2: { level3: '[Object: max depth reached]', }, }, }; expect(sanitizeObject(input)).toEqual(expected); }); it('should handle maxDepth of 0', () => { const input = { level1: { level2: 'nested', }, }; const config = { maxDepth: 0, }; const expected = '[Object: max depth reached]'; expect(sanitizeObject(input, config)).toBe(expected); }); }); describe('array handling', () => { it('should sanitize array elements', () => { const input = [ { username: 'user1', password: 'pass1' }, { username: 'user2', password: 'pass2' }, ]; const expected = [ { username: 'user1', password: '[REDACTED]' }, { username: 'user2', password: '[REDACTED]' }, ]; expect(sanitizeObject(input)).toEqual(expected); }); it('should handle nested arrays with depth limits', () => { const input = { users: [ { profile: { details: { secret: 'hidden', }, }, }, ], }; const config = { maxDepth: 2, }; const expected = { users: ['[Object: max depth reached]'], }; expect(sanitizeObject(input, config)).toEqual(expected); }); it('should handle mixed array content', () => { const input = ['string', 123, { password: 'secret' }, [1, 2, 3]]; const expected = ['string', 123, { password: '[REDACTED]' }, [1, 2, 3]]; expect(sanitizeObject(input)).toEqual(expected); }); }); describe('complex nested structures', () => { it('should handle deeply nested objects with sensitive data', () => { const input = { user: { profile: { personal: { email: 'test@example.com', password: 'secret123', }, preferences: { theme: 'dark', }, }, tokens: { access: 'token123', refresh: 'token456', }, }, }; const expected = { user: { profile: { personal: '[Object: max depth reached]', preferences: '[Object: max depth reached]', }, tokens: '[REDACTED]', }, }; expect(sanitizeObject(input)).toEqual(expected); }); it('should handle objects with non-sensitive nested fields', () => { const input = { request: { headers: { 'content-type': 'application/json', authorization: 'Bearer token123', }, body: { data: { name: 'John Doe', age: 30, }, }, }, }; const expected = { request: { headers: { 'content-type': '[Object: max depth reached]', authorization: '[REDACTED]', }, body: { data: '[Object: max depth reached]', }, }, }; expect(sanitizeObject(input)).toEqual(expected); }); }); describe('edge cases', () => { it('should handle empty objects', () => { expect(sanitizeObject({})).toEqual({}); }); it('should handle empty arrays', () => { expect(sanitizeObject([])).toEqual([]); }); it('should handle objects with only sensitive fields', () => { const input = { password: 'secret123', token: 'abc123', }; const expected = { password: '[REDACTED]', token: '[REDACTED]', }; expect(sanitizeObject(input)).toEqual(expected); }); it('should handle objects with only excluded fields', () => { const input = { email: 'test@example.com', phone: '123-456-7890', }; const config = { excludeFields: ['email', 'phone'], }; const expected = { email: '[REDACTED]', phone: '[REDACTED]', }; expect(sanitizeObject(input, config)).toEqual(expected); }); it('should handle unknown types', () => { const input = { func: () => 'test', symbol: Symbol('test'), }; const expected = { func: '[Unknown type]', symbol: '[Unknown type]', }; expect(sanitizeObject(input)).toEqual(expected); }); }); describe('configuration combinations', () => { it('should handle all configuration options together', () => { const input = { user: { profile: { email: 'test@example.com', password: 'secret123', phone: '123-456-7890', details: { address: { street: '123 Main St', city: 'Anytown', }, }, }, }, }; const config = { excludeFields: ['phone'], maxDepth: 2, }; const expected = { user: { profile: '[Object: max depth reached]', }, }; expect(sanitizeObject(input, config)).toEqual(expected); }); }); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FuaXRpemF0aW9uLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9taWRkbGV3YXJlL3V0aWxzL3Nhbml0aXphdGlvbi50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUEyQixNQUFNLGdCQUFnQixDQUFDO0FBRXpFLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxHQUFHLEVBQUU7SUFDcEMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtRQUM5QixRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO1lBQ2hDLEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxHQUFHLEVBQUU7Z0JBQ2xELE1BQU0sQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQzFELE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3RDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3hDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUMsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO2dCQUMxQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN4QyxNQUFNLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3BELENBQUMs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dUI7b0JBQ2pDLGFBQWEsRUFBRSxDQUFDLE9BQU8sQ0FBQztvQkFDeEIsUUFBUSxFQUFFLENBQUM7aUJBQ1osQ0FBQztnQkFDRixNQUFNLFFBQVEsR0FBRztvQkFDZixJQUFJLEVBQUU7d0JBQ0osT0FBTyxFQUFFLDZCQUE2QjtxQkFDdkM7aUJBQ0YsQ0FBQztnQkFDRixNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMxRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRlc2NyaWJlLCBpdCwgZXhwZWN0IH0gZnJvbSAndml0ZXN0JztcbmltcG9ydCB7IHNhbml0aXplT2JqZWN0LCB0eXBlIFNhbml0aXphdGlvbkNvbmZpZyB9IGZyb20gJy4vc2FuaXRpemF0aW9uJztcblxuZGVzY3JpYmUoJ1Nhbml0aXphdGlvbiBVdGlsaXR5JywgKCkgPT4ge1xuICBkZXNjcmliZSgnc2FuaXRpemVPYmplY3QnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ3ByaW1pdGl2ZSB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBwcmltaXRpdmUgdmFsdWVzIHVuY2hhbmdlZCcsICgpID0+IHtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KCd0ZXN0IHN0cmluZycpKS50b0JlKCd0ZXN0IHN0cmluZycpO1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoMTIzKSkudG9CZSgxMjMpO1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QodHJ1ZSkpLnRvQmUodHJ1ZSk7XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChmYWxzZSkpLnRvQmUoZmFsc2UpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG51bGwgYW5kIHVuZGVmaW5lZCcsICgpID0+IHtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KG51bGwpKS50b0JlKG51bGwpO1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QodW5kZWZpbmVkKSkudG9CZSh1bmRlZmluZWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2Vuc2l0aXZlIGZpZWxkIGRldGVjdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcmVkYWN0IHBhc3N3b3JkIGZpZWxkcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgdXNlcm5hbWU6ICd0ZXN0dXNlcicsXG4gICAgICAgICAgcGFzc3dvcmQ6ICdzZWNyZXQxMjMnLFxuICAgICAgICAgIGVtYWlsOiAndGVzdEBleGFtcGxlLmNvbScsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIHVzZXJuYW1lOiAndGVzdHVzZXInLFxuICAgICAgICAgIHBhc3N3b3JkOiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgZW1haWw6ICd0ZXN0QGV4YW1wbGUuY29tJyxcbiAgICAgICAgfTtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KGlucHV0KSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWRhY3QgdG9rZW4gZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ2FiYzEyMycsXG4gICAgICAgICAgcmVmcmVzaFRva2VuOiAnZGVmNDU2JyxcbiAgICAgICAgICB1c2VyVG9rZW46ICdnaGk3ODknLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHJlZnJlc2hUb2tlbjogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHVzZXJUb2tlbjogJ1tSRURBQ1RFRF0nLFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlZGFjdCBzZWNyZXQgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBhcGlTZWNyZXQ6ICdzZWNyZXQxMjMnLFxuICAgICAgICAgIGNsaWVudFNlY3JldDogJ3NlY3JldDQ1NicsXG4gICAgICAgICAgc2VjcmV0S2V5OiAnc2VjcmV0Nzg5JyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSB7XG4gICAgICAgICAgYXBpU2VjcmV0OiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgY2xpZW50U2VjcmV0OiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgc2VjcmV0S2V5OiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCkpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVkYWN0IGtleSBmaWVsZHMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0ge1xuICAgICAgICAgIGFwaUtleTogJ2tleTEyMycsXG4gICAgICAgICAgcHJpdmF0ZUtleTogJ2tleTQ1NicsXG4gICAgICAgICAgZW5jcnlwdGlvbktleTogJ2tleTc4OScsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIGFwaUtleTogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHByaXZhdGVLZXk6ICdbUkVEQUNURURdJyxcbiAgICAgICAgICBlbmNyeXB0aW9uS2V5OiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCkpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVkYWN0IGF1dGggZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiAnQmVhcmVyIHRva2VuMTIzJyxcbiAgICAgICAgICBhdXRoSGVhZGVyOiAnQmFzaWMgZFhObGNqcHdZWE56JyxcbiAgICAgICAgICBhdXRoVG9rZW46ICd0b2tlbjQ1NicsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIGF1dGhvcml6YXRpb246ICdbUkVEQUNURURdJyxcbiAgICAgICAgICBhdXRoSGVhZGVyOiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgYXV0aFRva2VuOiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCkpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGNhc2UtaW5zZW5zaXRpdmUgZmllbGQgZGV0ZWN0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBQQVNTV09SRDogJ3NlY3JldDEyMycsXG4gICAgICAgICAgQWNjZXNzVG9rZW46ICd0b2tlbjEyMycsXG4gICAgICAgICAgQVBJX1NFQ1JFVDogJ3NlY3JldDQ1NicsXG4gICAgICAgICAgcHJpdmF0ZV9rZXk6ICdrZXkxMjMnLFxuICAgICAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgdG9rZW4nLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICBQQVNTV09SRDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIEFjY2Vzc1Rva2VuOiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgQVBJX1NFQ1JFVDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHByaXZhdGVfa2V5OiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgQXV0aG9yaXphdGlvbjogJ1tSRURBQ1RFRF0nLFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2V4Y2x1ZGVGaWVsZHMgY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgcmVkYWN0IGV4cGxpY2l0bHkgZXhjbHVkZWQgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICB1c2VybmFtZTogJ3Rlc3R1c2VyJyxcbiAgICAgICAgICBlbWFpbDogJ3Rlc3RAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBob25lOiAnMTIzLTQ1Ni03ODkwJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgZXhjbHVkZUZpZWxkczogWydlbWFpbCcsICdwaG9uZSddLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICB1c2VybmFtZTogJ3Rlc3R1c2VyJyxcbiAgICAgICAgICBlbWFpbDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHBob25lOiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCwgY29uZmlnKSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBjb21iaW5lIGV4Y2x1ZGVGaWVsZHMgd2l0aCBzZW5zaXRpdmUgZmllbGQgZGV0ZWN0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICB1c2VybmFtZTogJ3Rlc3R1c2VyJyxcbiAgICAgICAgICBwYXNzd29yZDogJ3NlY3JldDEyMycsXG4gICAgICAgICAgZW1haWw6ICd0ZXN0QGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwaG9uZTogJzEyMy00NTYtNzg5MCcsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNvbmZpZzogU2FuaXRpemF0aW9uQ29uZmlnID0ge1xuICAgICAgICAgIGV4Y2x1ZGVGaWVsZHM6IFsnZW1haWwnXSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSB7XG4gICAgICAgICAgdXNlcm5hbWU6ICd0ZXN0dXNlcicsXG4gICAgICAgICAgcGFzc3dvcmQ6ICdbUkVEQUNURURdJyxcbiAgICAgICAgICBlbWFpbDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHBob25lOiAnMTIzLTQ1Ni03ODkwJyxcbiAgICAgICAgfTtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KGlucHV0LCBjb25maWcpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ21heERlcHRoIGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHJlc3BlY3QgbWF4RGVwdGggbGltaXQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0ge1xuICAgICAgICAgIGxldmVsMToge1xuICAgICAgICAgICAgbGV2ZWwyOiB7XG4gICAgICAgICAgICAgIGxldmVsMzoge1xuICAgICAgICAgICAgICAgIGxldmVsNDogJ3RvbyBkZWVwJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgbWF4RGVwdGg6IDIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIGxldmVsMToge1xuICAgICAgICAgICAgbGV2ZWwyOiAnW09iamVjdDogbWF4IGRlcHRoIHJlYWNoZWRdJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQsIGNvbmZpZykpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdXNlIGRlZmF1bHQgbWF4RGVwdGggb2YgMycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgbGV2ZWwxOiB7XG4gICAgICAgICAgICBsZXZlbDI6IHtcbiAgICAgICAgICAgICAgbGV2ZWwzOiB7XG4gICAgICAgICAgICAgICAgbGV2ZWw0OiAndG9vIGRlZXAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICBsZXZlbDE6IHtcbiAgICAgICAgICAgIGxldmVsMjoge1xuICAgICAgICAgICAgICBsZXZlbDM6ICdbT2JqZWN0OiBtYXggZGVwdGggcmVhY2hlZF0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBtYXhEZXB0aCBvZiAwJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBsZXZlbDE6IHtcbiAgICAgICAgICAgIGxldmVsMjogJ25lc3RlZCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgbWF4RGVwdGg6IDAsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0gJ1tPYmplY3Q6IG1heCBkZXB0aCByZWFjaGVkXSc7XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCwgY29uZmlnKSkudG9CZShleHBlY3RlZCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdhcnJheSBoYW5kbGluZycsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgc2FuaXRpemUgYXJyYXkgZWxlbWVudHMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gW1xuICAgICAgICAgIHsgdXNlcm5hbWU6ICd1c2VyMScsIHBhc3N3b3JkOiAncGFzczEnIH0sXG4gICAgICAgICAgeyB1c2VybmFtZTogJ3VzZXIyJywgcGFzc3dvcmQ6ICdwYXNzMicgfSxcbiAgICAgICAgXTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSBbXG4gICAgICAgICAgeyB1c2VybmFtZTogJ3VzZXIxJywgcGFzc3dvcmQ6ICdbUkVEQUNURURdJyB9LFxuICAgICAgICAgIHsgdXNlcm5hbWU6ICd1c2VyMicsIHBhc3N3b3JkOiAnW1JFREFDVEVEXScgfSxcbiAgICAgICAgXTtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KGlucHV0KSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgbmVzdGVkIGFycmF5cyB3aXRoIGRlcHRoIGxpbWl0cycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgdXNlcnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcHJvZmlsZToge1xuICAgICAgICAgICAgICAgIGRldGFpbHM6IHtcbiAgICAgICAgICAgICAgICAgIHNlY3JldDogJ2hpZGRlbicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgbWF4RGVwdGg6IDIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIHVzZXJzOiBbJ1tPYmplY3Q6IG1heCBkZXB0aCByZWFjaGVkXSddLFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQsIGNvbmZpZykpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG1peGVkIGFycmF5IGNvbnRlbnQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gWydzdHJpbmcnLCAxMjMsIHsgcGFzc3dvcmQ6ICdzZWNyZXQnIH0sIFsxLCAyLCAzXV07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0gWydzdHJpbmcnLCAxMjMsIHsgcGFzc3dvcmQ6ICdbUkVEQUNURURdJyB9LCBbMSwgMiwgM11dO1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbXBsZXggbmVzdGVkIHN0cnVjdHVyZXMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBkZWVwbHkgbmVzdGVkIG9iamVjdHMgd2l0aCBzZW5zaXRpdmUgZGF0YScsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgdXNlcjoge1xuICAgICAgICAgICAgcHJvZmlsZToge1xuICAgICAgICAgICAgICBwZXJzb25hbDoge1xuICAgICAgICAgICAgICAgIGVtYWlsOiAndGVzdEBleGFtcGxlLmNvbScsXG4gICAgICAgICAgICAgICAgcGFzc3dvcmQ6ICdzZWNyZXQxMjMnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBwcmVmZXJlbmNlczoge1xuICAgICAgICAgICAgICAgIHRoZW1lOiAnZGFyaycsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9rZW5zOiB7XG4gICAgICAgICAgICAgIGFjY2VzczogJ3Rva2VuMTIzJyxcbiAgICAgICAgICAgICAgcmVmcmVzaDogJ3Rva2VuNDU2JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSB7XG4gICAgICAgICAgdXNlcjoge1xuICAgICAgICAgICAgcHJvZmlsZToge1xuICAgICAgICAgICAgICBwZXJzb25hbDogJ1tPYmplY3Q6IG1heCBkZXB0aCByZWFjaGVkXScsXG4gICAgICAgICAgICAgIHByZWZlcmVuY2VzOiAnW09iamVjdDogbWF4IGRlcHRoIHJlYWNoZWRdJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0b2tlbnM6ICdbUkVEQUNURURdJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBvYmplY3RzIHdpdGggbm9uLXNlbnNpdGl2ZSBuZXN0ZWQgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICByZXF1ZXN0OiB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAgIGF1dGhvcml6YXRpb246ICdCZWFyZXIgdG9rZW4xMjMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJvZHk6IHtcbiAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIG5hbWU6ICdKb2huIERvZScsXG4gICAgICAgICAgICAgICAgYWdlOiAzMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWQgPSB7XG4gICAgICAgICAgcmVxdWVzdDoge1xuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAnY29udGVudC10eXBlJzogJ1tPYmplY3Q6IG1heCBkZXB0aCByZWFjaGVkXScsXG4gICAgICAgICAgICAgIGF1dGhvcml6YXRpb246ICdbUkVEQUNURURdJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICAgIGRhdGE6ICdbT2JqZWN0OiBtYXggZGVwdGggcmVhY2hlZF0nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2VkZ2UgY2FzZXMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbXB0eSBvYmplY3RzJywgKCkgPT4ge1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3Qoe30pKS50b0VxdWFsKHt9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbXB0eSBhcnJheXMnLCAoKSA9PiB7XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChbXSkpLnRvRXF1YWwoW10pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG9iamVjdHMgd2l0aCBvbmx5IHNlbnNpdGl2ZSBmaWVsZHMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0ge1xuICAgICAgICAgIHBhc3N3b3JkOiAnc2VjcmV0MTIzJyxcbiAgICAgICAgICB0b2tlbjogJ2FiYzEyMycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIHBhc3N3b3JkOiAnW1JFREFDVEVEXScsXG4gICAgICAgICAgdG9rZW46ICdbUkVEQUNURURdJyxcbiAgICAgICAgfTtcbiAgICAgICAgZXhwZWN0KHNhbml0aXplT2JqZWN0KGlucHV0KSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgb2JqZWN0cyB3aXRoIG9ubHkgZXhjbHVkZWQgZmllbGRzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgICBlbWFpbDogJ3Rlc3RAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBob25lOiAnMTIzLTQ1Ni03ODkwJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY29uZmlnOiBTYW5pdGl6YXRpb25Db25maWcgPSB7XG4gICAgICAgICAgZXhjbHVkZUZpZWxkczogWydlbWFpbCcsICdwaG9uZSddLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBleHBlY3RlZCA9IHtcbiAgICAgICAgICBlbWFpbDogJ1tSRURBQ1RFRF0nLFxuICAgICAgICAgIHBob25lOiAnW1JFREFDVEVEXScsXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCwgY29uZmlnKSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgdW5rbm93biB0eXBlcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgZnVuYzogKCkgPT4gJ3Rlc3QnLFxuICAgICAgICAgIHN5bWJvbDogU3ltYm9sKCd0ZXN0JyksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIGZ1bmM6ICdbVW5rbm93biB0eXBlXScsXG4gICAgICAgICAgc3ltYm9sOiAnW1Vua25vd24gdHlwZV0nLFxuICAgICAgICB9O1xuICAgICAgICBleHBlY3Qoc2FuaXRpemVPYmplY3QoaW5wdXQpKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbmZpZ3VyYXRpb24gY29tYmluYXRpb25zJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgYWxsIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0b2dldGhlcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB7XG4gICAgICAgICAgdXNlcjoge1xuICAgICAgICAgICAgcHJvZmlsZToge1xuICAgICAgICAgICAgICBlbWFpbDogJ3Rlc3RAZXhhbXBsZS5jb20nLFxuICAgICAgICAgICAgICBwYXNzd29yZDogJ3NlY3JldDEyMycsXG4gICAgICAgICAgICAgIHBob25lOiAnMTIzLTQ1Ni03ODkwJyxcbiAgICAgICAgICAgICAgZGV0YWlsczoge1xuICAgICAgICAgICAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgICAgICAgICAgIHN0cmVldDogJzEyMyBNYWluIFN0JyxcbiAgICAgICAgICAgICAgICAgIGNpdHk6ICdBbnl0b3duJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjb25maWc6IFNhbml0aXphdGlvbkNvbmZpZyA9IHtcbiAgICAgICAgICBleGNsdWRlRmllbGRzOiBbJ3Bob25lJ10sXG4gICAgICAgICAgbWF4RGVwdGg6IDIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAgIHVzZXI6IHtcbiAgICAgICAgICAgIHByb2ZpbGU6ICdbT2JqZWN0OiBtYXggZGVwdGggcmVhY2hlZF0nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChzYW5pdGl6ZU9iamVjdChpbnB1dCwgY29uZmlnKSkudG9FcXVhbChleHBlY3RlZCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==