# Attributes in response

?> **Starting from v2, we provide a shortcut for user to construct the attributes section efficiently instead of hard code the attribute information in template string.**

```javascript
const idp = require('samlify').IdentityProvider({
  // ...
  loginResponseTemplate: {
    context: '<samlp:Response ...'>,
    attributes: [
      { name: "mail", valueTag: "user.email", nameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:basic", valueXsiType: "xs:string" },
      { name: "name", valueTag: "user.name", nameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:basic", valueXsiType: "xs:string" }
    ]
  }
});
```

then the attributes part will be included in the template string:

```xml
<saml:AttributeStatement>
  <saml:Attribute 
    Name="mail"
    NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
    <saml:AttributeValue xsi:type="xs:string">
      {attrUserEmail}
    </saml:AttributeValue>
  </saml:Attribute>
  <saml:Attribute 
    Name="name"
    NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
    <saml:AttributeValue xsi:type="xs:string">
      {attrUserName}
    </saml:AttributeValue>
  </saml:Attribute>
</saml:AttributeStatement>
```

the tag name is auto-generated with prefix `attr` and the suffix is formatted as camel case of `valueTag` specified in the config.

# Custom templates

Developer can design their own request and response template for log-in and log-out respectively. There are optional parameters in setting object.

```javascript
const saml = require('samlify');

// load the template every time before each request/response is sent
const sp = saml.ServiceProvider({
  //...
  loginRequestTemplate: {
    context: readFileSync('./loginResponseTemplate.xml'),
  }
});
```

In SP configuration, `loginRequestTemplate` is the template of SAML Request, it can be either file name or XML string. This is the default template we've used in our module.

```xml
<samlp:AuthnRequest 
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"     
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
    ID="{ID}" 
    Version="2.0" 
    IssueInstant="{IssueInstant}" 
    Destination="{Destination}" 
    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" 
    AssertionConsumerServiceURL="{AssertionConsumerServiceURL}">
    
    <saml:Issuer>{Issuer}</saml:Issuer>
    <samlp:NameIDPolicy 
        Format="{NameIDFormat}" 
        AllowCreate="{AllowCreate}"/>
        
</samlp:AuthnRequest>
```

When you apply your own template, remember to do custom tag replacement when you send out the request. `replaceTagFromTemplate` is just the name here to illustrate but it's not fixed.

```javascript
router.get('/spinitsso-redirect', (req, res) => {
  sp.createLoginRequest(idp, 'redirect', url => {
    res.redirect(url);
  }, loginRequestTemplate => {
    // Here is the callback function for custom template
    // the input parameter is the value of loginRequestTemplate
    // The following is the input parameter of rcallback in different actions
    // sp.createLoginRequest -> loginRequestTemplate
    // sp.createLogoutResponse -> logoutResponseTemplate
    // idp.createLoginResponse -> loginResponseTemplate
    // idp.createLogoutRequest -> logoutRequestTemplate
    // replaceTagFromTemplate is a function to do dynamically substitution of tags
    return replaceTagFromTemplate(loginRequestTemplate);
  });
});
```

!> `replaceTagFromTemplate` must return the object containing `id` (response id) and `context` (string)
