// This is the Fetch User Profile Script for FxA
// Note the `acr_values` parameter, which requires AAL2 authenticator assurance level
// (https://pages.nist.gov/800-63-3/sp800-63b.html)
// Authenticator Assurance Level 2: AAL2 provides high confidence that the claimant controls an authenticator(s) bound to the subscriber’s account. Proof of possession and control of two different authentication factors is required through secure authentication protocol(s). Approved cryptographic techniques are required at AAL2 and above.
// We'd also be fine with AAL3 of course, though FxA supports up to AAL2 at this time.

// latest-dev URLs:
// Authorization endpoint: https://oauth-latest.dev.lcip.org/v1/authorization?acr_values=AAL2
// Token endpoint: https://oauth-latest.dev.lcip.org/v1/token
// scopes: openid profile
//
function(accessToken, ctx, cb) {
  // Auth0 already verified the id_token and it's signature at this stage
  // See docs at https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Firefox_Accounts/Introduction
  // See also https://github.com/mozilla/fxa-oauth-server/issues/519#issuecomment-367196241 for information on fields
  // Note that we assert this email is verified by FxA, though we do not check `amr` contains `email`. This is because
  // We currently assert `email_verified` to be true if it has ever been verified, not if it's "just been verified"
  var id_token = JSON.parse(jwt.decode(ctx.id_token));

  // Request additional profile info, such as picture, locale, etc.
  request.get('https://latest.dev.lcip.org/profile/v1/profile', {
    'headers': {
      'Authorization': 'Bearer ' + accessToken,
      'User-Agent': 'MozillaIAM-Auth0'
    }
  }, function(e, r, b) {
    if (e) return callback(e);
    if (r.statusCode !== 200) {
      return cb(new Error('Failed to fetch user profile. StatusCode:' + r.statusCode));
    }

    var p = JSON.parse(b);

    if (id_token.sub != p.sub) {
      return cb(new Error('sub does not match, this should not happen'));
    }

    return cb(null, {
      user_id: id_token.sub,
      picture: p.avatar,
      preferredLanguage: p.locale,
      email: p.email,
      email_verified: true,
      fxa_sub: id_token.sub,
      amr: id_token.amr,
      acr: id_token.acr,
      fxa_twoFactorAuthentication: p.twoFactorAuthentication
    });

  });
}

@@ -1562,19 +1562,25 @@
 rofile',
+%0A   
  %7B%0A
+  
     'hea
@@ -1588,16 +1588,18 @@
 ers': %7B%0A
+  
       'A
@@ -1644,16 +1644,18 @@
 ,%0A      
+  
 'User-Ag
@@ -1687,14 +1687,22 @@
     
+  
 %7D%0A  
+ 
+ 
 %7D,
+%0A   
  fun
@@ -1714,24 +1714,26 @@
 (e, r, b) %7B%0A
+  
     if (e) r
@@ -1751,24 +1751,26 @@
 ack(e);%0A    
+  
 if (r.status
@@ -1781,24 +1781,26 @@
  !== 200) %7B%0A
+  
       return
@@ -1875,27 +1875,31 @@
 Code));%0A    
+  
 %7D%0A%0A
+  
     var p = 
@@ -1914,24 +1914,26 @@
 se(b);%0A%0A    
+  
 if (id_token
@@ -1951,24 +1951,26 @@
 ub) %7B%0A      
+ 
+ 
 return cb(ne
@@ -2025,27 +2025,31 @@
 pen'));%0A    
+  
 %7D%0A%0A
+  
     return c
@@ -2064,16 +2064,18 @@
 %7B%0A      
+  
 user_id:
@@ -2095,16 +2095,18 @@
 ,%0A      
+ 
+ 
 picture:
@@ -2116,16 +2116,18 @@
 avatar,%0A
+  
       pr
@@ -2155,24 +2155,26 @@
 cale,%0A      
+ 
+ 
 email: p.ema
@@ -2177,16 +2177,18 @@
 .email,%0A
+  
       em
@@ -2209,24 +2209,26 @@
 true,%0A      
+ 
+ 
 fxa_sub: id_
@@ -2244,16 +2244,18 @@
 ,%0A      
+  
 amr: id_
@@ -2271,16 +2271,18 @@
 ,%0A      
+ 
+ 
 acr: id_
@@ -2292,16 +2292,18 @@
 en.acr,%0A
+  
       fx
@@ -2363,16 +2363,22 @@
     
+ 
+ 
 %7D);%0A
+    %7D
 %0A  
-%7D
 );%0A%7D

Correct indent