# verifiera.js

[Verifiera](https://en.wiktionary.org/wiki/verifiera): A JavaScript library to perform common operations on Personal Identification Numbers (Social Security Numbers), like: Validation, censoring the individual digits, calculating age and detecting gender.

[![npm](https://nodei.co/npm/verifiera.png?downloads=true&stars=true)](https://www.npmjs.com/package/verifiera)

### Key Information
[![license](https://img.shields.io/badge/dynamic/json?style=flat-square&color=success&label=license&query=license&url=https%3A%2F%2Fgitlab.com%2FMiladK%2Fverifiera.js%2F-%2Fraw%2Fmaster%2Fpackage.json)](https://gitlab.com/MiladK/verifiera.js/-/blob/master/LICENSE.md)
[![version](https://img.shields.io/badge/dynamic/json?color=success&label=version&query=version&url=https%3A%2F%2Fgitlab.com%2FMiladK%2Fverifiera.js%2F-%2Fraw%2Fmaster%2Fpackage.json)](https://gitlab.com/MiladK/verifiera.js/-/tags)
[![pipeline status](https://gitlab.com/MiladK/verifiera.js/badges/master/pipeline.svg)](https://gitlab.com/MiladK/verifiera.js/-/commits/master)
[![coverage report](https://gitlab.com/MiladK/verifiera.js/badges/master/coverage.svg)](https://gitlab.com/MiladK/verifiera.js/-/commits/master)
[![minified](https://badgen.net/bundlephobia/min/verifiera?color=green&style=flat-square)](https://bundlephobia.com/result?p=verifiera)
[![minzipped](https://badgen.net/bundlephobia/minzip/verifiera?color=green&style=flat-square)](https://bundlephobia.com/result?p=verifiera)

**verifiera.js**:
- Available for browsers, Node.js and as ES6 module.
- Shakable-tree.
- Respects semver.
- Well tested.
- Zero dependency.
- Written in TypeScript.
- Types are included.

### Supported Countries [Demo](https://miladk.gitlab.io/verifiera.js/)
- :cz: Czech Republic and :sk: Slovakia (Rodné Číslo)
- :dk: Denmark (CPR-Nummer)
- :fi: Finland (Henkilötunnus / Personbeteckning)
- :nl: Netherlands (Burgerservicenummer) _Validation only_
- :no: Norway (Fødselsnummer and D-nummer)
- :pl: Poland (PESEL)
- :se: Sweden (Personnummer and Samordningsnummer)

##### Upcoming Features
- Swedish organization no.
- Suggest a country or a feature!

### Installation
```shell script
npm i verifiera
```

### Usage
You can use ES6 import style:
```javascript
import {
  czechSlovakia,
  denmark,
  finland,
  netherlands,
  norway,
  poland,
  sweden
} from 'verifiera'
```
or CommonJS require style:
```javascript
const {
  czechSlovakia,
  denmark,
  finland,
  netherlands,
  norway,
  poland,
  sweden
} = require('verifiera')
```
Or even fetch to the browser as a script
```html
<script src="https://unpkg.com/verifiera@latest/dist/verifiera.js"></script>
<script>
const sweden = window.verifiera.sweden;
</script>
```
Then you can use the desired country tools by passing the personal number to it:
```javascript
const ssn = sweden('571124-1322')

ssn.validate() // true
ssn.getAge() // 62
ssn.getBirthday() // 1957-11-24
ssn.getCensored() // 571124-****
ssn.getGender() // f
ssn.getYear() // 1957
```

### Functions (Country Tools)
Country functions can be called as the following, where `ssn` is the personal number:

| Country     | Arguments             |
| ----------- | --------------------  |
| denmark     | (ssn, strict = false) |
| finland     | (ssn)                 |
| netherlands | (ssn)                 |
| norway      | (ssn)                 |
| poland      | (ssn)                 |
| sweden      | (ssn, strict = true)  |

A country function returns an object of the following country tools:

| Functions          | Returns              | Returns | Valid Example     | If Invalid | Notes       |
| ------------------ | -------------------- | ------- | ----------------- | ---------- | ----------- |
| validate()         | if the ssn valid     | bool    | `true`            | `false`    |             |
| getAge()           | Person's age         | int     | `62`              | `0`        |             |
| getBirthday()      | Person's birthday    | str     | `'1957-11-24'`    | `''`       |             |
| getCensored()      | Replaces identifiers | str     | `'571124-****'`   | `''`       |             |
| getGender()        | Person's gender      | str     | `'f'` or `'m'`    | `''`       |             |
| getYear()          | Year of birth        | int     | `1975`            | `0`        |             |
| isDNumber()        | Is it a D-number?    | bool    | `true`            | `false`    | Norway only |
| isCoordinationNo() | Is co-ordination no? | bool    | `true`            | `false`    | Sweden only |

### Additional Tools
#### isDNumber
- Detects whether a Norwegian personal number is a D-number.
- Returns `false` if the personal number looks like a D-number but isn't a valid one.

```javascript
import { norway } from 'verifiera'

norway('41018036736').isDNumber() // true
```

#### Auto-Detection of the Country
- If you have a valid personal number and you want to detect to which country it belongs, you can use the `detectCountry()` function.
- It only detects supported countries. :)

```javascript
import { detectCountry } from 'verifiera'

detectCountry('571124-1322') // sweden
```

Possible values are:
- czech_slovakia
- denmark
- finland
- netherlands
- norway
- poland
- sweden

#### Auto-Initiation of Country Tools
- This function will iterate over the list of all countries and return the correct one.
- Use when you don't know which country you are dealing with, but you only care about the operations. Ex: verify (or calculate ages for) a list of personal numbers that come from different countries.

```javascript
import { getCountryTools } from 'verifiera'

const ssn = getCountryTools('571124-1322')

ssn.validate() // true
ssn.getAge() // 62
ssn.getBirthday() // 1957-11-24
ssn.getCensored() // 571124-****
ssn.getGender() // f
ssn.getYear() // 1957
```

### Country Notes
- **Denmark:**
    - > However, in 2007 the available sequence numbers under this system for males born on 1 January 1965 ran out, and since October 2007 personal identification numbers do not always validate using the check digit. This had been predicted and announced several years in advance. Thus, most IT systems are presumed updated to accept numbers that fail the check-digit validation.
&mdash; [Wikipedia](https://en.wikipedia.org/wiki/Personal_identification_number_\(Denmark\))
    - Therefore, I see no use for performing a checksum on Danish personal numbers, because we will get false negatives. However, if you want to use the checksum, you can pass a `true` boolean after the personal number in `denmark('260783-1234', true)`, but this will consider some of real-world numbers invalud.
- **Netherlands:**
    - Dutch personal numbers don't hold any personal information like birthday or gender.
    - The only working function in the Dutch country tools is `validate()`. 
    - `getCensored()` returns `*********` for valid numbers.
- **Norway:**
    - `validate()` returns true for both valid normal personal numbers and valid D-numbers. If it's important to differentiate between them, please use `isDNumber()`
- **Sweden:**
    - In Sweden, some companies add the century digits as a part of the personal number, or remove the -/+ signs between the date of birth and the four individual digits.
These variations are not part of the official standard as specified by Skatteverket. So I included a switch for strict mode:
       - `strict = true` Supports the official standard format only _(default)_.
       - `strict = false` Supports the popular non-standard format.
    - `validate()` returns true for both valid normal personal numbers and valid coordination numbers. If it's important to differentiate between them, please use `isCoordinationNo()`

### Issues and Bugs
Please submit your requests or report issues and bugs [here](https://gitlab.com/MiladK/verifiera.js/issues).

### Contribution
Feel free to discuss any addition or improvement before you submit a merge request.
Please don't commit anything in the `dist` folder. This folder gets updated just before a release.

### PHP Sister
This library was introduced originally in PHP as [Bekräfta](https://github.com/Milad/bekrafta)

### License
MIT
