@criipto/verify-react 0.0.3 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/criipto-verify-react.cjs.js +1 -1
  2. package/dist/criipto-verify-react.cjs.js.map +1 -1
  3. package/dist/{criipto-verify-react.cjs.css → criipto-verify-react.css} +0 -0
  4. package/dist/criipto-verify-react.esm.js +1 -1
  5. package/dist/criipto-verify-react.esm.js.map +1 -1
  6. package/dist/provider.d.ts +5 -0
  7. package/package.json +2 -2
  8. package/.storybook/addons/client/preset.js +0 -5
  9. package/.storybook/addons/client/register.js +0 -47
  10. package/.storybook/main.js +0 -17
  11. package/.storybook/preview.js +0 -21
  12. package/.vscode/settings.json +0 -3
  13. package/dist/criipto-verify-react.esm.css +0 -75
  14. package/netlify.toml +0 -3
  15. package/src/components/AuthMethodButton/AuthMethodButton.css +0 -75
  16. package/src/components/AuthMethodButton/AuthMethodButton.tsx +0 -128
  17. package/src/components/AuthMethodButton/logos/beeid.png +0 -0
  18. package/src/components/AuthMethodButton/logos/digid.png +0 -0
  19. package/src/components/AuthMethodButton/logos/dkmitid.png +0 -0
  20. package/src/components/AuthMethodButton/logos/dknemid.png +0 -0
  21. package/src/components/AuthMethodButton/logos/ftnmobile.png +0 -0
  22. package/src/components/AuthMethodButton/logos/itsme.png +0 -0
  23. package/src/components/AuthMethodButton/logos/nobankid.png +0 -0
  24. package/src/components/AuthMethodButton/logos/novipps.png +0 -0
  25. package/src/components/AuthMethodButton/logos/sebankid.png +0 -0
  26. package/src/components/AuthMethodButton/logos/sofort.png +0 -0
  27. package/src/components/AuthMethodButton/package.json +0 -3
  28. package/src/components/AuthMethodSelector/AuthMethodSelector.stories.tsx +0 -21
  29. package/src/components/AuthMethodSelector/AuthMethodSelector.tsx +0 -43
  30. package/src/components/AuthMethodSelector/package.json +0 -3
  31. package/src/context.ts +0 -28
  32. package/src/global.d.ts +0 -4
  33. package/src/index.ts +0 -5
  34. package/src/provider.tsx +0 -45
  35. package/src/utils.ts +0 -129
  36. package/webpack.config.js +0 -72
@@ -1,128 +0,0 @@
1
- import React, {useContext, useEffect, useState} from 'react';
2
-
3
- import beeid from './logos/beeid.png';
4
- import digid from './logos/digid.png';
5
- import dkmitid from './logos/dkmitid.png';
6
- import dknemid from './logos/dknemid.png';
7
- import ftnmobile from './logos/ftnmobile.png';
8
- import itsme from './logos/itsme.png';
9
- import nobankid from './logos/nobankid.png';
10
- import novipps from './logos/novipps.png';
11
- import sebankid from './logos/sebankid.png';
12
- import sofort from './logos/sofort.png';
13
-
14
- import './AuthMethodButton.css';
15
- import CriiptoVerifyContext from '../../context';
16
-
17
- interface ButtonProps {
18
- className?: string,
19
- children: React.ReactNode,
20
- onClick?: React.MouseEventHandler
21
- }
22
-
23
- interface AnchorButtonProps extends ButtonProps {
24
- href: string
25
- }
26
-
27
- export function AnchorButton(props: AnchorButtonProps) {
28
- return (
29
- <a className={`criipto-verify-button ${props.className}`} href={props.href} onClick={props.onClick}>{props.children}</a>
30
- );
31
- }
32
-
33
- export function Button(props: ButtonProps) {
34
- return (
35
- <button className={`criipto-verify-button ${props.className}`} type="button" onClick={props.onClick}>{props.children}</button>
36
- );
37
- }
38
-
39
- interface AuthMethodButtonProps {
40
- acrValue: string,
41
- href?: string;
42
- onClick?: React.MouseEventHandler,
43
- children?: React.ReactNode,
44
- 'data-testid'?: string,
45
- className?: string,
46
- redirectUri?: string
47
- }
48
-
49
- export default function AuthMethodButton(props: AuthMethodButtonProps) {
50
- const {acrValue} = props;
51
- const context = useContext(CriiptoVerifyContext);
52
- const className = `criipto-verify-button-eid ${acrValueToClassName(acrValue)}${props.className ? ` ${props.className}` : ''}`;
53
-
54
- const [href, setHref] = useState(props.href);
55
-
56
- useEffect(() => {
57
- if (props.href) return;
58
-
59
- context.buildAuthorizeUrl({
60
- redirectUri: props.redirectUri,
61
- acrValues: acrValue
62
- }).then(setHref)
63
- .catch(console.error);
64
- }, [props.href, acrValue]);
65
-
66
- if (href) {
67
- return (
68
- <AnchorButton {...props} href={href} className={className}>
69
- {acrValueToLogo(acrValue) ? <img src={acrValueToLogo(acrValue)} alt="" /> : null}
70
- <span>{props.children}</span>
71
- </AnchorButton>
72
- );
73
- }
74
-
75
- return (
76
- <Button {...props} className={className}>
77
- {acrValueToLogo(acrValue) ? <img src={acrValueToLogo(acrValue)} alt="" /> : null}
78
- <span>{props.children}</span>
79
- </Button>
80
- );
81
- }
82
-
83
- function acrValueToClassName(value: string) {
84
- value = value.replace('urn:grn:authn:', '');
85
- const segments = value.split(':');
86
- const classNames = segments.reduce((memo: string[], segment: string) => {
87
- if (memo.length) {
88
- return memo.concat([`${memo[memo.length-1]}-${segment}`])
89
- } else {
90
- return memo.concat([segment]);
91
- }
92
- }, []);
93
-
94
- return classNames.map(className => `criipto-verify-button-${className}`).join(' ');
95
- }
96
-
97
- function acrValueToLogo(value : string) {
98
- if (value.startsWith('urn:grn:authn:be:eid')) {
99
- return beeid;
100
- }
101
- if (value.startsWith('urn:grn:authn:nl:digid')) {
102
- return digid;
103
- }
104
- if (value.startsWith('urn:grn:authn:dk:mitid')) {
105
- return dkmitid;
106
- }
107
- if (value.startsWith('urn:grn:authn:dk:nemid')) {
108
- return dknemid;
109
- }
110
- if (value.startsWith('urn:grn:authn:fi')) {
111
- return ftnmobile;
112
- }
113
- if (value.startsWith('urn:grn:authn:itsme')) {
114
- return itsme;
115
- }
116
- if (value.startsWith('urn:grn:authn:se:bankid')) {
117
- return sebankid;
118
- }
119
- if (value.startsWith('urn:grn:authn:de:sofort')) {
120
- return sofort;
121
- }
122
- if (value.startsWith('urn:grn:authn:no:bankid')) {
123
- return nobankid;
124
- }
125
- if (value.startsWith('urn:grn:authn:no:vipps')) {
126
- return novipps;
127
- }
128
- }
@@ -1,3 +0,0 @@
1
- {
2
- "main": "./AuthMethodButton.tsx"
3
- }
@@ -1,21 +0,0 @@
1
- import React from 'react';
2
- import { ComponentStory, ComponentMeta } from '@storybook/react';
3
-
4
- import AuthMethodSelector from './AuthMethodSelector';
5
- import CriiptoVerifyProvider from '../../provider';
6
-
7
- export default {
8
- title: 'Components/AuthMethodSelector',
9
- component: AuthMethodSelector,
10
- } as ComponentMeta<typeof AuthMethodSelector>;
11
-
12
- // More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
13
- const Template: ComponentStory<typeof AuthMethodSelector> = (args, {globals}) => {
14
- return (
15
- <CriiptoVerifyProvider domain={globals.domain} clientID={globals.clientID} redirectUri="https://httpbin.org/get">
16
- <AuthMethodSelector {...args} />
17
- </CriiptoVerifyProvider>
18
- );
19
- };
20
-
21
- export const Default = Template.bind({});
@@ -1,43 +0,0 @@
1
- import {OpenIDConfiguration} from '@criipto/auth-js';
2
- import React, { useContext, useEffect, useState } from 'react';
3
- import CriiptoVerifyContext from '../../context';
4
- import { acrValueToTitle, filterAcrValues, Language } from '../../utils';
5
- import AuthMethodButton from '../AuthMethodButton/AuthMethodButton';
6
-
7
- interface Props {
8
- acrValues?: string[],
9
- language?: Language,
10
- onSelect?: (acrValue: string) => void,
11
- redirectUri?: string
12
- }
13
-
14
- export default function AuthMethodSelector(props: Props) {
15
- const context = useContext(CriiptoVerifyContext);
16
- const language = props.language || 'en';
17
- const [configuration, setConfiguration] = useState<OpenIDConfiguration | null>(null);
18
-
19
- useEffect(() => {
20
- (async () => {
21
- const configuration = await context.fetchOpenIDConfiguration();
22
- setConfiguration(configuration);
23
- })();
24
- }, []);
25
-
26
- const acrValues = filterAcrValues(props.acrValues ?? configuration?.acr_values_supported ?? []);
27
-
28
- return (
29
- <React.Fragment>
30
- {acrValues.map(acrValue => (
31
- <AuthMethodButton
32
- acrValue={acrValue}
33
- key={acrValue}
34
- onClick={props.onSelect ? (() => props.onSelect!(acrValue)) : undefined}
35
- redirectUri={props.redirectUri}
36
- >
37
- {acrValueToTitle(language, acrValue).title}<br />
38
- {acrValueToTitle(language, acrValue).subtitle}
39
- </AuthMethodButton>
40
- ))}
41
- </React.Fragment>
42
- )
43
- }
@@ -1,3 +0,0 @@
1
- {
2
- "main": "./AuthMethodSelector.tsx"
3
- }
package/src/context.ts DELETED
@@ -1,28 +0,0 @@
1
- import {OpenIDConfiguration, AuthorizeUrlParamsOptional} from '@criipto/auth-js';
2
- import { createContext } from 'react';
3
-
4
- export interface CriiptoVerifyContextInterface {
5
- loginWithRedirect: () => Promise<void>,
6
- fetchOpenIDConfiguration: () => Promise<OpenIDConfiguration>,
7
- buildAuthorizeUrl: (options?: AuthorizeUrlParamsOptional) => Promise<string>
8
- }
9
-
10
- /**
11
- * @ignore
12
- */
13
- const stub = (): never => {
14
- throw new Error('You forgot to wrap your component in <CriiptoVerifyProvider>.');
15
- };
16
-
17
- /**
18
- * @ignore
19
- */
20
- const initialContext = {
21
- loginWithRedirect: stub,
22
- fetchOpenIDConfiguration: stub,
23
- buildAuthorizeUrl: stub
24
- };
25
-
26
- const CriiptoVerifyContext = createContext<CriiptoVerifyContextInterface>(initialContext);
27
-
28
- export default CriiptoVerifyContext;
package/src/global.d.ts DELETED
@@ -1,4 +0,0 @@
1
- declare module "*.png" {
2
- const value: string;
3
- export default value;
4
- }
package/src/index.ts DELETED
@@ -1,5 +0,0 @@
1
- import {default as CriiptoVerifyProvider} from './provider';
2
- import {default as AuthMethodSelector} from './components/AuthMethodSelector';
3
- import {default as AuthMethodButton} from './components/AuthMethodButton';
4
-
5
- export {CriiptoVerifyProvider, AuthMethodSelector, AuthMethodButton};
package/src/provider.tsx DELETED
@@ -1,45 +0,0 @@
1
- import React, {useMemo, useState} from 'react';
2
- import CriiptoAuth, {AuthorizeUrlParamsOptional} from '@criipto/auth-js';
3
-
4
- import CriiptoVerifyContext, {CriiptoVerifyContextInterface} from './context';
5
-
6
- export interface CriiptoVerifyProviderOptions {
7
- domain: string
8
- clientID: string
9
- redirectUri?: string;
10
- children: React.ReactNode
11
- }
12
-
13
- const CriiptoVerifyProvider = (props: CriiptoVerifyProviderOptions) : JSX.Element => {
14
- const [client] = useState(
15
- () => new CriiptoAuth({
16
- domain: props.domain,
17
- clientID: props.clientID,
18
- store: sessionStorage,
19
- redirectUri: props.redirectUri
20
- })
21
- );
22
-
23
- const context = useMemo<CriiptoVerifyContextInterface>(() => {
24
- return {
25
- loginWithRedirect: () => client.redirect.authorize({
26
- redirectUri: window.location.origin
27
- }),
28
- fetchOpenIDConfiguration: () => client.fetchOpenIDConfiguration(),
29
- buildAuthorizeUrl: async (options?: AuthorizeUrlParamsOptional) => {
30
- return await client.buildAuthorizeUrl(client.buildAuthorizeParams(options || {}));
31
- }
32
- }
33
- }, [
34
- client,
35
- props.redirectUri
36
- ]);
37
-
38
- return (
39
- <CriiptoVerifyContext.Provider value={context}>
40
- {props.children}
41
- </CriiptoVerifyContext.Provider>
42
- );
43
- }
44
-
45
- export default CriiptoVerifyProvider
package/src/utils.ts DELETED
@@ -1,129 +0,0 @@
1
- export const DKMITID_PREFIX = 'urn:grn:authn:dk:mitid';
2
-
3
- export function lowestMitIDValue(input: string[]) : string | null {
4
- let dkmitidMethod : string | null = null;
5
-
6
- input.forEach(s => {
7
- if (s.startsWith(DKMITID_PREFIX)) {
8
- if (!dkmitidMethod) {
9
- dkmitidMethod = s;
10
- } else {
11
- let newLevel = s.replace(DKMITID_PREFIX, '');
12
- let oldLevel = dkmitidMethod.replace(DKMITID_PREFIX, '');
13
- if (newLevel === ':low' && [':substantial', ':high'].includes(oldLevel)) {
14
- dkmitidMethod = s;
15
- }
16
- else if (newLevel === ':substantial' && oldLevel === ':high') {
17
- dkmitidMethod = s;
18
- }
19
- }
20
- }
21
- });
22
-
23
- return dkmitidMethod;
24
- }
25
-
26
- function autoTitleCase(input: string) {
27
- var segments = input.split(/:|-/).map(segment => {
28
- segment = segment.replace(/id(\s|$)/, 'ID');
29
- if (segment.length === 2) return segment.toUpperCase();
30
- return segment.substr(0, 1).toUpperCase() + segment.substr(1);
31
- });
32
- return segments.join(' ');
33
- }
34
-
35
- export type Language = 'en' | 'da' | 'sv' | 'nb';
36
-
37
- export function acrValueToTitle(language: Language, value: string) : {title: string, subtitle?: string} {
38
- value = value.replace('urn:grn:authn:', '');
39
-
40
- if (value.startsWith('be:eid')) {
41
- return {title: autoTitleCase(value).replace('BEEID', 'Belgian eID')};
42
- }
43
- if (value.startsWith('nl:digid')) {
44
- return {title: autoTitleCase(value).replace('NL ', '')};
45
- }
46
- if (value.startsWith('dk:mitid')) {
47
- return {title: 'MitID'};
48
- }
49
- if (value.startsWith('dk:nemid')) {
50
- let subtitle : string | undefined = undefined;
51
- let suffix = value.replace('dk:nemid:', '');
52
-
53
- if (suffix === 'poces') {
54
- if (language === 'en') subtitle = 'Personal';
55
- if (language === 'da') subtitle = 'Personlig';
56
- if (language === 'sv') subtitle = 'Personlig';
57
- if (language === 'nb') subtitle = 'Personlig';
58
- }
59
- if (suffix === 'moces') {
60
- if (language === 'en') subtitle = 'Employee key card';
61
- if (language === 'da') subtitle = 'Medarbejder nøglekort';
62
- if (language === 'sv') subtitle = 'Anställd nyckelkort';
63
- if (language === 'nb') subtitle = 'Ansatt nøkkelkort';
64
- }
65
- if (suffix === 'moces:codefile') {
66
- if (language === 'en') subtitle = 'Employee key file';
67
- if (language === 'da') subtitle = 'Medarbejder nøglefil';
68
- if (language === 'sv') subtitle = 'Anställd nyckelfil';
69
- if (language === 'nb') subtitle = 'Ansatt nøkkelfil';
70
- }
71
-
72
- return {
73
- title: 'NemID',
74
- subtitle
75
- }
76
- }
77
- if (value.startsWith('fi')) {
78
- return {title: autoTitleCase(value).replace('FI', 'FTN')};
79
- }
80
- if (value.startsWith('itsme')) {
81
- return {title: autoTitleCase(value).replace('me', 'ME')};
82
- }
83
- if (value.startsWith('se:bankid')) {
84
- let subtitle : string | undefined = undefined;
85
- let suffix = value.replace('se:bankid:', '');
86
-
87
- if (suffix === 'same-device') {
88
- if (language === 'en') subtitle = 'On this device';
89
- if (language === 'da') subtitle = 'På denne enhed';
90
- if (language === 'sv') subtitle = 'På denna enheten';
91
- if (language === 'nb') subtitle = 'På denne enheten';
92
- }
93
- if (suffix === 'another-device') {
94
- if (language === 'en') subtitle = 'With your SSN';
95
- if (language === 'da') subtitle = 'Med dit personnummer';
96
- if (language === 'sv') subtitle = 'Med ditt personnummer';
97
- if (language === 'nb') subtitle = 'Med personnummeret ditt';
98
- }
99
- if (suffix === 'another-device:qr') {
100
- if (language === 'en') subtitle = 'With QR Code';
101
- if (language === 'da') subtitle = 'Med QR-kode';
102
- if (language === 'sv') subtitle = 'Med QR-kod';
103
- if (language === 'nb') subtitle = 'Med QR-kode';
104
- }
105
-
106
- return {title: 'BankID', subtitle};
107
- }
108
- if (value.startsWith('de:sofort')) {
109
- return {title: autoTitleCase(value).replace('DE ', '')};
110
- }
111
- if (value.startsWith('no:bankid')) {
112
- return {title: autoTitleCase(value).replace('NO ', '')};
113
- }
114
- if (value.startsWith('no:vipps')) {
115
- return {title: autoTitleCase(value).replace('NO ', '')};
116
- }
117
-
118
- return {title: autoTitleCase(value)};
119
- }
120
-
121
- export function filterAcrValues(input: string[]) {
122
- let original = input.slice();
123
- let dkmitidMethod : string | null = lowestMitIDValue(input);
124
-
125
- if (dkmitidMethod) {
126
- return input.filter(s => !s.startsWith(DKMITID_PREFIX)).concat([dkmitidMethod]).sort((a, b) => original.indexOf(a) - original.indexOf(b));
127
- }
128
- return input;
129
- }
package/webpack.config.js DELETED
@@ -1,72 +0,0 @@
1
- const path = require('path');
2
- const nodeExternals = require('webpack-node-externals');
3
- const MiniCssExtractPlugin = require("mini-css-extract-plugin");
4
- const fs = require('fs');
5
-
6
- module.exports = {
7
- mode: 'production',
8
- devtool: "source-map",
9
- experiments: {
10
- outputModule: true
11
- },
12
- entry: {
13
- 'criipto-verify-react.esm': {
14
- import: path.resolve(__dirname, 'src/index.ts'),
15
- library: {
16
- type: 'module'
17
- }
18
- },
19
- 'criipto-verify-react.cjs': {
20
- import: path.resolve(__dirname, 'src/index.ts'),
21
- library: {
22
- type: 'commonjs'
23
- }
24
- }
25
- },
26
- externalsPresets: { node: true },
27
- externals: [nodeExternals()],
28
- plugins: [
29
- new MiniCssExtractPlugin()
30
- ],
31
- module: {
32
- rules: [
33
- {
34
- test: /\.css$/i,
35
- use: [
36
- {
37
- loader: MiniCssExtractPlugin.loader,
38
- },
39
- {
40
- loader: "css-loader",
41
- options: {
42
- sourceMap: false
43
- }
44
- }
45
- ],
46
- },
47
- {
48
- test: /\.tsx?$/,
49
- exclude: /node_modules/,
50
- loader: 'ts-loader',
51
- },
52
- {
53
- test: /\.(png|jpg|gif|svg)$/i,
54
- use: [
55
- {
56
- loader: 'url-loader',
57
- options: {
58
- limit: true,
59
- },
60
- },
61
- ]
62
- }
63
- ]
64
- },
65
- resolve: {
66
- extensions: ['.tsx', '.ts', '.js'],
67
- },
68
- output: {
69
- path: path.resolve(__dirname, 'dist'),
70
- filename: '[name].js'
71
- }
72
- };