| 
						
						
							
								
							
						
						
					 | 
					@ -23,7 +23,6 @@ import { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  AttestationCredentialJSON | 
					 | 
					 | 
					  AttestationCredentialJSON | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} from './interfaces/simplewebauthn'; | 
					 | 
					 | 
					} from './interfaces/simplewebauthn'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; | 
					 | 
					 | 
					import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import base64url from 'base64url'; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { JwtService } from '@nestjs/jwt'; | 
					 | 
					 | 
					import { JwtService } from '@nestjs/jwt'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { AuthDeviceDto } from '@ghostfolio/api/app/auth-device/auth-device.dto'; | 
					 | 
					 | 
					import { AuthDeviceDto } from '@ghostfolio/api/app/auth-device/auth-device.dto'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { RequestWithUser } from '@ghostfolio/common/types'; | 
					 | 
					 | 
					import { RequestWithUser } from '@ghostfolio/common/types'; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -48,9 +47,6 @@ export class WebAuthService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  public async generateAttestationOptions() { | 
					 | 
					 | 
					  public async generateAttestationOptions() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const user = this.request.user; | 
					 | 
					 | 
					    const user = this.request.user; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const devices = await this.deviceService.authDevices({ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      where: { userId: user.id } | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const opts: GenerateAttestationOptionsOpts = { | 
					 | 
					 | 
					    const opts: GenerateAttestationOptionsOpts = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      rpName: 'Ghostfolio', | 
					 | 
					 | 
					      rpName: 'Ghostfolio', | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -59,21 +55,6 @@ export class WebAuthService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      userName: user.alias, | 
					 | 
					 | 
					      userName: user.alias, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      timeout: 60000, | 
					 | 
					 | 
					      timeout: 60000, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      attestationType: 'indirect', | 
					 | 
					 | 
					      attestationType: 'indirect', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      /** | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       * Passing in a user's list of already-registered authenticator IDs here prevents users from | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       * registering the same device multiple times. The authenticator will simply throw an error in | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       * the browser if it's asked to perform an attestation when one of these ID's already resides | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       * on it. | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       */ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      excludeCredentials: devices.map((device) => ({ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        id: device.credentialId, | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        type: 'public-key', | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        transports: ['usb', 'ble', 'nfc', 'internal'] | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      })), | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      /** | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       * The optional authenticatorSelection property allows for specifying more constraints around | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       * the types of authenticators that users to can use for attestation | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       */ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      authenticatorSelection: { | 
					 | 
					 | 
					      authenticatorSelection: { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        userVerification: 'preferred', | 
					 | 
					 | 
					        userVerification: 'preferred', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        requireResidentKey: false | 
					 | 
					 | 
					        requireResidentKey: false | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -82,10 +63,6 @@ export class WebAuthService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const options = generateAttestationOptions(opts); | 
					 | 
					 | 
					    const options = generateAttestationOptions(opts); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    /** | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					     * The server needs to temporarily remember this value for verification, so don't lose it until | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					     * after you verify an authenticator response. | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					     */ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    await this.userService.updateUser({ | 
					 | 
					 | 
					    await this.userService.updateUser({ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      data: { | 
					 | 
					 | 
					      data: { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        authChallenge: options.challenge | 
					 | 
					 | 
					        authChallenge: options.challenge | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -139,57 +116,47 @@ export class WebAuthService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          credentialPublicKey, | 
					 | 
					 | 
					          credentialPublicKey, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          credentialId: credentialID, | 
					 | 
					 | 
					          credentialId: credentialID, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          counter, | 
					 | 
					 | 
					          counter, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          name: deviceName, | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          User: { connect: { id: user.id } } | 
					 | 
					 | 
					          User: { connect: { id: user.id } } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        }); | 
					 | 
					 | 
					        }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      } | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      return { | 
					 | 
					 | 
					      return { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        createdAt: existingDevice.createdAt.toISOString(), | 
					 | 
					 | 
					        createdAt: existingDevice.createdAt.toISOString(), | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        id: existingDevice.id, | 
					 | 
					 | 
					        id: existingDevice.id | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					        name: existingDevice.name | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      }; | 
					 | 
					 | 
					      }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    throw new InternalServerErrorException('An unknown error occurred'); | 
					 | 
					 | 
					    throw new InternalServerErrorException('An unknown error occurred'); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  public async generateAssertionOptions(userId: string) { | 
					 | 
					 | 
					  public async generateAssertionOptions(deviceId: string) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    const devices = await this.deviceService.authDevices({ | 
					 | 
					 | 
					    const device = await this.deviceService.authDevice({ id: deviceId }); | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					      where: { userId: userId } | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    if (devices.length === 0) { | 
					 | 
					 | 
					    if (!device) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					      throw new Error('No registered auth devices found.'); | 
					 | 
					 | 
					      throw new Error('Device not found'); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const opts: GenerateAssertionOptionsOpts = { | 
					 | 
					 | 
					    const opts: GenerateAssertionOptionsOpts = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      timeout: 60000, | 
					 | 
					 | 
					      timeout: 60000, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      allowCredentials: devices.map((dev) => ({ | 
					 | 
					 | 
					      allowCredentials: [ | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        id: dev.credentialId, | 
					 | 
					 | 
					        { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        type: 'public-key', | 
					 | 
					 | 
					          id: device.credentialId, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        transports: ['usb', 'ble', 'nfc', 'internal'] | 
					 | 
					 | 
					          type: 'public-key', | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					      })), | 
					 | 
					 | 
					          transports: ['usb', 'ble', 'nfc', 'internal'] | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					      /** | 
					 | 
					 | 
					        } | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					       * This optional value controls whether or not the authenticator needs be able to uniquely | 
					 | 
					 | 
					      ], | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					       * identify the user interacting with it (via built-in PIN pad, fingerprint scanner, etc...) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					       */ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      userVerification: 'preferred', | 
					 | 
					 | 
					      userVerification: 'preferred', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      rpID: this.rpID | 
					 | 
					 | 
					      rpID: this.rpID | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }; | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const options = generateAssertionOptions(opts); | 
					 | 
					 | 
					    const options = generateAssertionOptions(opts); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    /** | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					     * The server needs to temporarily remember this value for verification, so don't lose it until | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					     * after you verify an authenticator response. | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					     */ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    await this.userService.updateUser({ | 
					 | 
					 | 
					    await this.userService.updateUser({ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      data: { | 
					 | 
					 | 
					      data: { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        authChallenge: options.challenge | 
					 | 
					 | 
					        authChallenge: options.challenge | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      }, | 
					 | 
					 | 
					      }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      where: { | 
					 | 
					 | 
					      where: { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        id: userId | 
					 | 
					 | 
					        id: device.userId | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      } | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }); | 
					 | 
					 | 
					    }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -197,22 +164,16 @@ export class WebAuthService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  public async verifyAssertion( | 
					 | 
					 | 
					  public async verifyAssertion( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    userId: string, | 
					 | 
					 | 
					    deviceId: string, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    credential: AssertionCredentialJSON | 
					 | 
					 | 
					    credential: AssertionCredentialJSON | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  ) { | 
					 | 
					 | 
					  ) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    const user = await this.userService.user({ id: userId }); | 
					 | 
					 | 
					    const device = await this.deviceService.authDevice({ id: deviceId }); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    const bodyCredIDBuffer = base64url.toBuffer(credential.rawId); | 
					 | 
					 | 
					    if (!device) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    const devices = await this.deviceService.authDevices({ | 
					 | 
					 | 
					      throw new Error('Device not found'); | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					      where: { credentialId: bodyCredIDBuffer } | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    if (devices.length !== 1) { | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      throw new InternalServerErrorException( | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        `Could not find authenticator matching ${credential.id}` | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      ); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    const authenticator = devices[0]; | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const user = await this.userService.user({ id: device.userId }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    let verification: VerifiedAssertion; | 
					 | 
					 | 
					    let verification: VerifiedAssertion; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    try { | 
					 | 
					 | 
					    try { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -222,9 +183,9 @@ export class WebAuthService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        expectedOrigin: this.expectedOrigin, | 
					 | 
					 | 
					        expectedOrigin: this.expectedOrigin, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        expectedRPID: this.rpID, | 
					 | 
					 | 
					        expectedRPID: this.rpID, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        authenticator: { | 
					 | 
					 | 
					        authenticator: { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					          credentialID: authenticator.credentialId, | 
					 | 
					 | 
					          credentialID: device.credentialId, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					          credentialPublicKey: authenticator.credentialPublicKey, | 
					 | 
					 | 
					          credentialPublicKey: device.credentialPublicKey, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					          counter: authenticator.counter | 
					 | 
					 | 
					          counter: device.counter | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      }; | 
					 | 
					 | 
					      }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      verification = verifyAssertionResponse(opts); | 
					 | 
					 | 
					      verification = verifyAssertionResponse(opts); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -236,12 +197,11 @@ export class WebAuthService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const { verified, assertionInfo } = verification; | 
					 | 
					 | 
					    const { verified, assertionInfo } = verification; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    if (verified) { | 
					 | 
					 | 
					    if (verified) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      // Update the authenticator's counter in the DB to the newest count in the assertion
 | 
					 | 
					 | 
					      device.counter = assertionInfo.newCounter; | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					      authenticator.counter = assertionInfo.newCounter; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      await this.deviceService.updateAuthDevice({ | 
					 | 
					 | 
					      await this.deviceService.updateAuthDevice({ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        data: authenticator, | 
					 | 
					 | 
					        data: device, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        where: { id_userId: { id: authenticator.id, userId: user.id } } | 
					 | 
					 | 
					        where: { id: device.id } | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      }); | 
					 | 
					 | 
					      }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      return this.jwtService.sign({ | 
					 | 
					 | 
					      return this.jwtService.sign({ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |