@pax2pay/model-banking 0.1.509 → 0.1.511

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 (95) hide show
  1. package/Card/Restriction/Merchant.ts +19 -94
  2. package/Card/Restriction/merchants/Merchant.ts +28 -0
  3. package/Card/Restriction/merchants/airlines.json +957 -0
  4. package/Card/Restriction/merchants/hotels.json +252 -0
  5. package/Card/Restriction/merchants/index.ts +765 -0
  6. package/Card/Restriction/merchants/misc.json +139 -0
  7. package/User/Access/Permission.ts +47 -0
  8. package/User/Access/index.ts +19 -0
  9. package/User/Identity.ts +32 -0
  10. package/User/JWT/Payload.ts +56 -0
  11. package/User/JWT/Signer.ts +39 -0
  12. package/User/JWT/index.ts +57 -0
  13. package/User/Me.ts +15 -0
  14. package/User/Password.ts +43 -0
  15. package/User/index.ts +68 -0
  16. package/dist/cjs/Card/Restriction/Merchant.d.ts +3 -9
  17. package/dist/cjs/Card/Restriction/Merchant.js +18 -87
  18. package/dist/cjs/Card/Restriction/Merchant.js.map +1 -1
  19. package/dist/cjs/Card/Restriction/merchants/Merchant.d.ts +12 -0
  20. package/dist/cjs/Card/Restriction/merchants/Merchant.js +26 -0
  21. package/dist/cjs/Card/Restriction/merchants/Merchant.js.map +1 -0
  22. package/dist/cjs/Card/Restriction/merchants/index.d.ts +763 -0
  23. package/dist/cjs/Card/Restriction/merchants/index.js +767 -0
  24. package/dist/cjs/Card/Restriction/merchants/index.js.map +1 -0
  25. package/dist/cjs/User/Access/Permission.d.ts +20 -0
  26. package/dist/cjs/User/Access/Permission.js +47 -0
  27. package/dist/cjs/User/Access/Permission.js.map +1 -0
  28. package/dist/cjs/User/Access/index.d.ts +11 -0
  29. package/dist/cjs/User/Access/index.js +16 -0
  30. package/dist/cjs/User/Access/index.js.map +1 -0
  31. package/dist/cjs/User/Identity.d.ts +16 -0
  32. package/dist/cjs/User/Identity.js +32 -0
  33. package/dist/cjs/User/Identity.js.map +1 -0
  34. package/dist/cjs/User/JWT/Payload.d.ts +43 -0
  35. package/dist/cjs/User/JWT/Payload.js +42 -0
  36. package/dist/cjs/User/JWT/Payload.js.map +1 -0
  37. package/dist/cjs/User/JWT/Signer.d.ts +23 -0
  38. package/dist/cjs/User/JWT/Signer.js +39 -0
  39. package/dist/cjs/User/JWT/Signer.js.map +1 -0
  40. package/dist/cjs/User/JWT/index.d.ts +25 -0
  41. package/dist/cjs/User/JWT/index.js +59 -0
  42. package/dist/cjs/User/JWT/index.js.map +1 -0
  43. package/dist/cjs/User/Me.d.ts +9 -0
  44. package/dist/cjs/User/Me.js +14 -0
  45. package/dist/cjs/User/Me.js.map +1 -0
  46. package/dist/cjs/User/Password.d.ts +20 -0
  47. package/dist/cjs/User/Password.js +44 -0
  48. package/dist/cjs/User/Password.js.map +1 -0
  49. package/dist/cjs/User/index.d.ts +46 -0
  50. package/dist/cjs/User/index.js +54 -0
  51. package/dist/cjs/User/index.js.map +1 -0
  52. package/dist/cjs/pax2pay.d.ts +2 -1
  53. package/dist/cjs/pax2pay.js +5 -3
  54. package/dist/cjs/pax2pay.js.map +1 -1
  55. package/dist/mjs/Card/Restriction/Merchant.d.ts +3 -9
  56. package/dist/mjs/Card/Restriction/Merchant.js +18 -87
  57. package/dist/mjs/Card/Restriction/Merchant.js.map +1 -1
  58. package/dist/mjs/Card/Restriction/merchants/Merchant.d.ts +12 -0
  59. package/dist/mjs/Card/Restriction/merchants/Merchant.js +23 -0
  60. package/dist/mjs/Card/Restriction/merchants/Merchant.js.map +1 -0
  61. package/dist/mjs/Card/Restriction/merchants/index.d.ts +763 -0
  62. package/dist/mjs/Card/Restriction/merchants/index.js +764 -0
  63. package/dist/mjs/Card/Restriction/merchants/index.js.map +1 -0
  64. package/dist/mjs/User/Access/Permission.d.ts +20 -0
  65. package/dist/mjs/User/Access/Permission.js +44 -0
  66. package/dist/mjs/User/Access/Permission.js.map +1 -0
  67. package/dist/mjs/User/Access/index.d.ts +11 -0
  68. package/dist/mjs/User/Access/index.js +13 -0
  69. package/dist/mjs/User/Access/index.js.map +1 -0
  70. package/dist/mjs/User/Identity.d.ts +16 -0
  71. package/dist/mjs/User/Identity.js +28 -0
  72. package/dist/mjs/User/Identity.js.map +1 -0
  73. package/dist/mjs/User/JWT/Payload.d.ts +43 -0
  74. package/dist/mjs/User/JWT/Payload.js +39 -0
  75. package/dist/mjs/User/JWT/Payload.js.map +1 -0
  76. package/dist/mjs/User/JWT/Signer.d.ts +23 -0
  77. package/dist/mjs/User/JWT/Signer.js +35 -0
  78. package/dist/mjs/User/JWT/Signer.js.map +1 -0
  79. package/dist/mjs/User/JWT/index.d.ts +25 -0
  80. package/dist/mjs/User/JWT/index.js +55 -0
  81. package/dist/mjs/User/JWT/index.js.map +1 -0
  82. package/dist/mjs/User/Me.d.ts +9 -0
  83. package/dist/mjs/User/Me.js +11 -0
  84. package/dist/mjs/User/Me.js.map +1 -0
  85. package/dist/mjs/User/Password.d.ts +20 -0
  86. package/dist/mjs/User/Password.js +41 -0
  87. package/dist/mjs/User/Password.js.map +1 -0
  88. package/dist/mjs/User/index.d.ts +46 -0
  89. package/dist/mjs/User/index.js +51 -0
  90. package/dist/mjs/User/index.js.map +1 -0
  91. package/dist/mjs/pax2pay.d.ts +2 -1
  92. package/dist/mjs/pax2pay.js +2 -1
  93. package/dist/mjs/pax2pay.js.map +1 -1
  94. package/package.json +1 -1
  95. package/pax2pay.ts +2 -1
@@ -0,0 +1,139 @@
1
+ [
2
+ {
3
+ "name": "PARKWING",
4
+ "mccs": [
5
+ 4582
6
+ ],
7
+ "category": "Airports and Terminals",
8
+ "startsWith": [
9
+ "PARKWING"
10
+ ]
11
+ },
12
+ {
13
+ "name": "Albergo - Food and drinks",
14
+ "mccs": [
15
+ 5812
16
+ ],
17
+ "category": "Food and drinks",
18
+ "startsWith": [
19
+ "ALBERGO"
20
+ ]
21
+ },
22
+ {
23
+ "name": "Amtrak",
24
+ "mccs": [
25
+ 4112
26
+ ],
27
+ "category": "Alternative Transportation",
28
+ "startsWith": [
29
+ "AMTRAK"
30
+ ]
31
+ },
32
+ {
33
+ "name": "Italo Treno",
34
+ "mccs": [
35
+ 4112
36
+ ],
37
+ "category": "Alternative Transportation",
38
+ "contains": [
39
+ "ITALOTRENO"
40
+ ]
41
+ },
42
+ {
43
+ "name": "ILSA WEB",
44
+ "mccs": [
45
+ 4112
46
+ ],
47
+ "category": "Advertising",
48
+ "contains": [
49
+ "ILSA WEB"
50
+ ]
51
+ },
52
+ {
53
+ "name": "Rail Ninja",
54
+ "mccs": [
55
+ 4722,
56
+ 4789
57
+ ],
58
+ "category": "Alternative Transportation",
59
+ "startsWith": [
60
+ "RailNinja"
61
+ ]
62
+ },
63
+ {
64
+ "name": "Irish Rail",
65
+ "mccs": [
66
+ 4789,
67
+ 4112
68
+ ],
69
+ "category": "Alternative Transportation",
70
+ "startsWith": [
71
+ "IRISH RAIL"
72
+ ]
73
+ },
74
+ {
75
+ "name": "Österreichische Bundesbahnen",
76
+ "mccs": [
77
+ 4111
78
+ ],
79
+ "category": "Alternative Transportation",
80
+ "startsWith": [
81
+ "OEBB"
82
+ ]
83
+ },
84
+ {
85
+ "name": "Rail Europe",
86
+ "mccs": [
87
+ 4722
88
+ ],
89
+ "category": "Alternative Transportation",
90
+ "startsWith": [
91
+ "RAIL EUROPE"
92
+ ]
93
+ },
94
+ {
95
+ "name": "Via Rail Canada",
96
+ "mccs": [
97
+ 4112
98
+ ],
99
+ "category": "Alternative Transportation",
100
+ "startsWith": [
101
+ "VIA RAIL"
102
+ ]
103
+ },
104
+ {
105
+ "name": "Direct Ferries",
106
+ "mccs": [
107
+ 4111,
108
+ 4411
109
+ ],
110
+ "category": "Alternative Transportation",
111
+ "startsWith": [
112
+ "DIRECTF"
113
+ ]
114
+ },
115
+ {
116
+ "name": "Booking.com",
117
+ "mccs": [
118
+ 4722
119
+ ],
120
+ "category": "Travel Agency",
121
+ "startsWith": [
122
+ "BKG*"
123
+ ]
124
+ },
125
+ {
126
+ "name": "Advertising",
127
+ "mccs": [
128
+ 7311,
129
+ 5818
130
+ ],
131
+ "contains": [
132
+ "FACEBK",
133
+ "google *ad",
134
+ "googleadwords",
135
+ "facebook"
136
+ ],
137
+ "category": "Advertising"
138
+ }
139
+ ]
@@ -0,0 +1,47 @@
1
+ import { isly } from "isly"
2
+ import { typedly } from "typedly"
3
+
4
+ export type Permission = Partial<Record<Permission.Collection, Permission.Level>>
5
+ export namespace Permission {
6
+ export type Realm = Omit<Permission, "user">
7
+ export type Global = Pick<Permission, "user">
8
+ export function check(constraint: Permission, privilege: Permission): boolean {
9
+ return typedly.Object.entries(constraint).every(
10
+ ([collection, level]) =>
11
+ Permission.Level.get(privilege[collection]) >= Permission.Level.get(level) ||
12
+ Permission.Level.get(privilege["*"]) >= Permission.Level.get(level)
13
+ )
14
+ }
15
+ export type Level = typeof Level.values[number]
16
+ export namespace Level {
17
+ export const values = ["read", "write", "developer", "admin"] as const
18
+ export const type = isly.string(values)
19
+ export function get(level: Level | undefined): number {
20
+ return level ? value[level] : 0
21
+ }
22
+ export const value: Record<Level, number> = {
23
+ read: 1,
24
+ write: 2,
25
+ developer: 3,
26
+ admin: 4,
27
+ } as const
28
+ }
29
+ export type Collection = typeof Collection.values[number]
30
+ export namespace Collection {
31
+ export const values = [
32
+ "account",
33
+ "card",
34
+ "log",
35
+ "operation",
36
+ "organization",
37
+ "rule", // realm rules
38
+ "settlement",
39
+ "transaction",
40
+ "treasury",
41
+ "user",
42
+ "*",
43
+ ] as const
44
+ export const type = isly.string(values)
45
+ }
46
+ export const type = isly.record<Permission>(Collection.type, Level.type)
47
+ }
@@ -0,0 +1,19 @@
1
+ import { isly } from "isly"
2
+ import { Permission as AccessPermission } from "./Permission"
3
+
4
+ /** read < write < developer < admin */
5
+ export interface Access {
6
+ uk?: Access.Permission.Realm
7
+ eea?: Access.Permission.Realm
8
+ test?: Access.Permission.Realm
9
+ "*"?: Access.Permission.Global
10
+ }
11
+ export namespace Access {
12
+ export import Permission = AccessPermission
13
+ export const type = isly.object({
14
+ uk: Access.Permission.type.optional(),
15
+ eea: Access.Permission.type.optional(),
16
+ test: Access.Permission.type.optional(),
17
+ "*": isly.object({ user: Access.Permission.Level.type.optional() }).optional(),
18
+ })
19
+ }
@@ -0,0 +1,32 @@
1
+ import { gracely } from "gracely"
2
+ import { http } from "cloudly-http"
3
+ import { Realm } from "../Realm"
4
+ import { Access } from "./Access"
5
+ import { JWT } from "./JWT"
6
+
7
+ export class Identity {
8
+ get realm(): Realm {
9
+ return this.payload.realm
10
+ }
11
+ constructor(public readonly payload: JWT.Payload, private readonly jwt: string) {}
12
+
13
+ authenticate(constraint: Access.Permission | Access.Permission[]): Identity | gracely.Error {
14
+ let allowed: boolean
15
+ if (Array.isArray(constraint))
16
+ allowed = constraint.some(c => this.authenticate(c))
17
+ else
18
+ allowed = Access.Permission.check(constraint, this.payload.permission)
19
+ return allowed ? this : gracely.client.forbidden()
20
+ }
21
+
22
+ /** Key will default to production jwt verification key */
23
+ static async open(
24
+ authorization: string | undefined,
25
+ options: { whitelist?: JWT.Whitelist; key?: string }
26
+ ): Promise<Identity | gracely.Error> {
27
+ const jwt = authorization?.startsWith("Bearer ") ? authorization.replace("Bearer ", "") : undefined
28
+ const payload = jwt ? await JWT.open({ public: options.key }, options.whitelist).verify(jwt) : undefined
29
+ return jwt && payload ? new Identity(payload, jwt) : gracely.client.unauthorized()
30
+ }
31
+ }
32
+ export namespace Identity {}
@@ -0,0 +1,56 @@
1
+ import { authly } from "authly"
2
+ import { isly } from "isly"
3
+ import { Realm } from "../../Realm"
4
+ import { Access } from "../Access"
5
+
6
+ export type Payload = Payload.LongTerm | Payload.ShortTerm
7
+ export namespace Payload {
8
+ export interface Creatable {
9
+ sub: string
10
+ permission: Access.Permission
11
+ realm: Realm
12
+ }
13
+ export namespace Creatable {
14
+ export const type = isly.object<Creatable>({
15
+ sub: isly.string(),
16
+ permission: Access.Permission.type,
17
+ realm: Realm.type,
18
+ })
19
+ }
20
+ export interface Base extends authly.Payload {
21
+ aud: string
22
+ iat: number
23
+ iss: string
24
+ sub: string
25
+ permission: Access.Permission
26
+ realm: Realm
27
+ }
28
+ export namespace Base {
29
+ export const type = isly.object<Payload>({
30
+ aud: isly.string(),
31
+ iat: isly.number(),
32
+ iss: isly.string(),
33
+ sub: isly.string(),
34
+ permission: Access.Permission.type,
35
+ realm: Realm.type,
36
+ })
37
+ }
38
+ export interface LongTerm extends Base {
39
+ id: string
40
+ }
41
+ export namespace LongTerm {
42
+ export const type = Base.type.extend<LongTerm>({ id: isly.string() })
43
+ }
44
+ export interface ShortTerm extends Base {
45
+ exp: number
46
+ }
47
+ export namespace ShortTerm {
48
+ export const type = Base.type.extend<ShortTerm>({ exp: isly.number() })
49
+ }
50
+
51
+ export const configuration = {
52
+ aud: "https://banking.pax2pay.app",
53
+ iss: "pax2pay",
54
+ }
55
+ export const type = isly.union<Payload>(LongTerm.type, ShortTerm.type)
56
+ }
@@ -0,0 +1,39 @@
1
+ import { authly } from "authly"
2
+ import { Payload } from "./Payload"
3
+
4
+ export class Signer {
5
+ constructor(private readonly key?: { public?: string; private?: string }) {}
6
+
7
+ /** Duration in seconds */
8
+ async sign(data: Payload.Creatable, duration: number | "infinite" = 60 * 60 * 12): Promise<string | undefined> {
9
+ let result: string | undefined
10
+ if (duration === "infinite") {
11
+ const signer = Signer.create({ key: this.key })
12
+ result = await signer?.sign({ id: authly.Identifier.generate(16), ...data })
13
+ } else {
14
+ const signer = Signer.create({ key: this.key, duration })
15
+ result = await signer?.sign({ ...data })
16
+ }
17
+ return result
18
+ }
19
+
20
+ static open(key?: { public?: string; private?: string }): Signer {
21
+ return new this(key)
22
+ }
23
+ }
24
+ export namespace Signer {
25
+ export function create<T extends authly.Payload>(options: {
26
+ key?: { public?: string; private?: string }
27
+ duration?: number
28
+ }): authly.Issuer<T> | undefined {
29
+ const signer = authly.Issuer.create(
30
+ Payload.configuration.iss,
31
+ authly.Algorithm.RS256(options.key?.public, options.key?.private)
32
+ )
33
+ if (signer) {
34
+ signer.duration = options.duration
35
+ signer.audience = Payload.configuration.aud
36
+ }
37
+ return signer
38
+ }
39
+ }
@@ -0,0 +1,57 @@
1
+ import { authly } from "authly"
2
+ import { Realm } from "../../Realm"
3
+ import { Payload as JWTPayload } from "./Payload"
4
+ import { Signer as JWTSigner } from "./Signer"
5
+
6
+ export class JWT {
7
+ #verifier?: authly.Verifier<JWT.Payload>
8
+ private get verifier(): authly.Verifier<JWT.Payload> | undefined {
9
+ if (!this.#verifier && this.key?.public) {
10
+ const algorithm = authly.Algorithm.RS256(this.key.public)
11
+ this.#verifier = algorithm ? authly.Verifier.create(algorithm) : undefined
12
+ }
13
+ return this.#verifier
14
+ }
15
+ #signer?: JWTSigner
16
+ private get signer(): JWTSigner | undefined {
17
+ return this.key?.private ? (this.#signer ??= JWTSigner.open(this.key)) : undefined
18
+ }
19
+ get sign() {
20
+ return this.signer?.sign
21
+ }
22
+ private constructor(
23
+ private readonly key?: { public?: string; private?: string },
24
+ readonly whitelist?: JWT.Whitelist
25
+ ) {}
26
+
27
+ async verify(token: string): Promise<JWT.Payload | undefined> {
28
+ const verified = await this.verifier?.verify(token, JWT.Payload.configuration.aud)
29
+ delete verified?.token
30
+ return JWT.Payload.type.is(verified) &&
31
+ verified?.iss == JWT.Payload.configuration.iss &&
32
+ (verified.exp || (verified.id && this.whitelist?.[verified.realm]?.some(e => e.id === verified.id)))
33
+ ? verified
34
+ : undefined
35
+ }
36
+ async unpack(token: string): Promise<JWT.Payload | undefined> {
37
+ const unpacked = await JWT.unpack(token)
38
+ delete unpacked?.token
39
+ return unpacked
40
+ }
41
+
42
+ static open(key?: { private?: string; public?: string }, whitelist?: JWT.Whitelist): JWT {
43
+ return new this({ private: key?.private, public: key?.public ?? JWT.key }, whitelist)
44
+ }
45
+ }
46
+ export namespace JWT {
47
+ export import Signer = JWTSigner
48
+ export type Whitelist = Partial<Record<Realm, Payload.LongTerm[]>>
49
+ export async function unpack(token: string): Promise<JWT.Payload | undefined> {
50
+ const algorithm = authly.Algorithm.RS256(undefined)
51
+ const verifier = algorithm ? authly.Verifier.create<JWT.Payload>(algorithm) : undefined
52
+ return verifier?.unpack(token)
53
+ }
54
+ export import Payload = JWTPayload
55
+ export const key =
56
+ "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2W8CD2kpfS4QIRV2/rgm4NVvsvJsYNMHtnIl9ADvO3A81hAmRKvOAPVoXICe6+EuZ47jGjGL7f48GEoQuITfBPv/MosCDj1YhJ56ILDynCSd8FlxDrhv8pl5IquST7tcL6Hc6m+vuvoTLrFQ5QqNxv0a5eDd/YTrWv7SUuRfBEhYd/wMysGynN3QauHqy5ceBCt1nv1MJLGlSzczMRK7wjy1zi2g9NCHZBOoo1HXOpi727Xh+YXHc9EP2TN0oOXyxykv45nkGIDI0Qek3/pfkavClBffc1sEqA+rUx7YqRN9KGYxwLMLug+NOOh3ptqjfobXbR5fx/sUWhvcjUMTE1JreTrWYbGmVnjd/SeYSClfmGhdTBUfqnZbaABv0ruTXva18qRhP4y143vHMk/k8HzbuROTKAzrtEeLIjgwUgDcnE+JwDqcb8tKSGV6i++TiTldlSBCRTT4dK2hpHJje80b2abqtrbCkxbJlT98UsAAoiq2eW1X6lYmCfiGCJPkfswibQ2tPAKKNe/2xuHPsjx4FuXGmV0dbzmCwSIQoApXqOvKzoNFi6AaKIjxfNmiEigLwKpNrw08H0lVZbq/9MMxI3TzMTZjY9QmBKVLSGy3Z6IJqZpyK22lv7whJcllG0Qw8tv8+7wmC8SR3+4jpuxuFGZ+69CW+otx+CPMJjcCAwEAAQ=="
57
+ }
package/User/Me.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { isly } from "isly"
2
+ import { Realm } from "../Realm"
3
+
4
+ export interface Me {
5
+ email: string
6
+ password: string
7
+ realm: Realm
8
+ }
9
+ export namespace Me {
10
+ export const type = isly.object<Me>({
11
+ email: isly.string(),
12
+ password: isly.string(),
13
+ realm: Realm.type,
14
+ })
15
+ }
@@ -0,0 +1,43 @@
1
+ import { cryptly } from "cryptly"
2
+ import { gracely } from "gracely"
3
+ import { isoly } from "isoly"
4
+ import { isly } from "isly"
5
+
6
+ export interface Password {
7
+ hash: cryptly.Password.Hash
8
+ changed: isoly.DateTime
9
+ }
10
+ export namespace Password {
11
+ export interface Creatable {
12
+ new: string
13
+ repeat: string
14
+ }
15
+ export namespace Creatable {
16
+ export const type = isly.object<Creatable>({
17
+ new: isly.string(),
18
+ repeat: isly.string(),
19
+ })
20
+ }
21
+ export async function create(creatable: Creatable, pepper: string | undefined): Promise<Password | gracely.Error> {
22
+ let result: Awaited<ReturnType<typeof create>>
23
+ if (creatable.new !== creatable.repeat)
24
+ result = gracely.client.forbidden("The new password and the repeated password do not match.")
25
+ else if (!pepper)
26
+ result = gracely.server.backendFailure("The password cannot be created without a pepper.")
27
+ else
28
+ result = { hash: await hash(creatable.new, pepper), changed: isoly.DateTime.now() }
29
+ return result
30
+ }
31
+ export function salt(): string {
32
+ return cryptly.Base64.encode(cryptly.RandomValue.generate(new Uint8Array(64)).toString())
33
+ }
34
+ export async function hash(password: string, pepper: string): Promise<cryptly.Password.Hash> {
35
+ return cryptly.Password.hash(signer(pepper), password, salt())
36
+ }
37
+ export async function verify(password: string, hash: cryptly.Password.Hash, pepper: string): Promise<boolean> {
38
+ return cryptly.Password.verify(signer(pepper), hash, password)
39
+ }
40
+ function signer(pepper: string): { sign: (data: string) => Promise<string> } {
41
+ return cryptly.Signer.create("HMAC", "SHA-512", pepper)
42
+ }
43
+ }
package/User/index.ts ADDED
@@ -0,0 +1,68 @@
1
+ import { isoly } from "isoly"
2
+ import { isly } from "isly"
3
+ import { Realm } from "../Realm"
4
+ import { Access as UserAccess } from "./Access"
5
+ import { Identity as UserIdentity } from "./Identity"
6
+ import { JWT as UserJWT } from "./JWT"
7
+ import { Me as UserMe } from "./Me"
8
+ import { Password as UserPassword } from "./Password"
9
+
10
+ export interface User {
11
+ email: string
12
+ access: User.Access
13
+ changed: isoly.DateTime
14
+ created: isoly.DateTime
15
+ password: {
16
+ changed: isoly.DateTime
17
+ }
18
+ }
19
+ export namespace User {
20
+ export import Access = UserAccess
21
+ export import Identity = UserIdentity
22
+ export import JWT = UserJWT
23
+ export import Me = UserMe
24
+ export import Password = UserPassword
25
+ export function fromInvite(invite: Invite): User {
26
+ const now = isoly.DateTime.now()
27
+ return {
28
+ email: invite.email,
29
+ access: invite.access,
30
+ changed: now,
31
+ created: now,
32
+ password: {
33
+ changed: now,
34
+ },
35
+ }
36
+ }
37
+ export function toJWTPayloadCreatable(user: User, realm: Realm): User.JWT.Payload.Creatable {
38
+ return {
39
+ sub: user.email,
40
+ permission: { ...(user.access[realm] ?? {}), ...(user.access["*"] ?? {}) },
41
+ realm,
42
+ }
43
+ }
44
+ export interface Creatable {
45
+ invite: string
46
+ password: Password.Creatable
47
+ }
48
+ export namespace Creatable {
49
+ export const type = isly.object<Creatable>({
50
+ invite: isly.string(),
51
+ password: isly.object({ new: isly.string(), repeat: isly.string() }),
52
+ })
53
+ }
54
+ export interface Invite {
55
+ id: string
56
+ email: string
57
+ access: Access
58
+ }
59
+ export namespace Invite {
60
+ export interface Creatable {
61
+ email: string
62
+ access: Access
63
+ }
64
+ export namespace Creatable {
65
+ export const type = isly.object<Creatable>({ email: isly.string(), access: Access.type })
66
+ }
67
+ }
68
+ }
@@ -3,14 +3,8 @@ import { isly as isly2 } from "isly2";
3
3
  import type { Transaction } from "../../Transaction";
4
4
  export type Merchant = typeof Merchant.values[number];
5
5
  export declare namespace Merchant {
6
- const values: readonly ["united airlines", "american air", "british airways", "air france", "lufthansa", "qantas", "alitalia", "saudi air", "sas", "air india", "air algerie", "emirates", "air malta", "etihad air", "tap", "avianca", "gulf air", "aer lingus", "turkish air", "royal air maroc", "tunis air", "austrian air", "flydubai", "cebu air", "thai airways", "china airlines", "malaysia airlines", "iberia", "qatar air", "ana air", "jet blue", "middle east airlines", "lot polish airlines", "norwegian air", "air arabia", "easyjet", "ryanair", "air china", "ethiopian airlines", "wizz air"];
7
- const type: isly.Type<"united airlines" | "american air" | "british airways" | "air france" | "lufthansa" | "qantas" | "alitalia" | "saudi air" | "sas" | "air india" | "air algerie" | "emirates" | "air malta" | "etihad air" | "tap" | "avianca" | "gulf air" | "aer lingus" | "turkish air" | "royal air maroc" | "tunis air" | "austrian air" | "flydubai" | "cebu air" | "thai airways" | "china airlines" | "malaysia airlines" | "iberia" | "qatar air" | "ana air" | "jet blue" | "middle east airlines" | "lot polish airlines" | "norwegian air" | "air arabia" | "easyjet" | "ryanair" | "air china" | "ethiopian airlines" | "wizz air">;
8
- const type2: isly2.String<"united airlines" | "american air" | "british airways" | "air france" | "lufthansa" | "qantas" | "alitalia" | "saudi air" | "sas" | "air india" | "air algerie" | "emirates" | "air malta" | "etihad air" | "tap" | "avianca" | "gulf air" | "aer lingus" | "turkish air" | "royal air maroc" | "tunis air" | "austrian air" | "flydubai" | "cebu air" | "thai airways" | "china airlines" | "malaysia airlines" | "iberia" | "qatar air" | "ana air" | "jet blue" | "middle east airlines" | "lot polish airlines" | "norwegian air" | "air arabia" | "easyjet" | "ryanair" | "air china" | "ethiopian airlines" | "wizz air">;
9
- type Checker = (merchant: Merchant, transaction: Transaction.Creatable.CardTransaction | Transaction.PreTransaction.Authorization) => boolean;
10
- type Attribute = {
11
- mccs: string[];
12
- checkers?: Checker[];
13
- };
14
- const attributes: Record<Merchant, Attribute>;
6
+ const values: ("ryanair" | "easyjet" | "wizzair" | "aer lingus" | "air malta" | "vueling" | "jet2" | "eurowings" | "turkish air" | "tap" | "pegasus" | "royal air maroc" | "qatar air" | "blue island" | "klm" | "iberia" | "emirates" | "aegean airlines" | "tui" | "united airlines" | "cathay pacific airlines" | "air serbia" | "copa air" | "bamboo airways" | "latam airlines" | "flydubai" | "condor" | "transavia" | "austrian air" | "alitalia" | "apg airlines" | "iceland air" | "flyone" | "avianca" | "brussels airlines" | "saudia" | "aeromexico" | "gulf air" | "ethiopian airlines" | "egypt air" | "albawings" | "iberojet" | "norwegian air" | "vistara" | "air greenland" | "sky express" | "air canada" | "philippine airlines" | "south african airlink" | "air benelux" | "tunisair" | "lufthansa" | "corendon airlines" | "uganda airlines" | "freebird airlines" | "kenya airway" | "kuwait air" | "british airways" | "czech airlines" | "lot polish airlines" | "volotea" | "flybe" | "bulgaria air" | "sas" | "qantas" | "air india" | "air europa" | "royal jordanian" | "virgin atlantic" | "flexflight" | "rwandair" | "hahn air" | "american air" | "pakistan international airlines" | "singapore airlines" | "delta air lines" | "croatia airlines" | "air asia" | "hawaiian airlines" | "oman air" | "etihad air" | "middle east airlines" | "logan air" | "aurigny" | "eastern airways" | "sun express" | "spirit air" | "air france" | "malaysia airlines" | "finnair" | "swiss air" | "air china" | "ana air" | "ae bsp" | "thai airways" | "jet blue" | "westjet" | "aerolineas" | "air seoul" | "azerbaijan airlines" | "air dolomiti" | "bangkok airways" | "china airlines" | "china eastern airlines" | "eva air" | "jetstar airways" | "km malta airlines" | "ita airways" | "china southern airlines" | "world2fly" | "sata denmark" | "air baltic" | "ajet" | "flynorse" | "hainan air" | "sichuan airlines" | "korean air" | "gol airlines" | "azul brazilian airlines" | "flysafair" | "air mauritius" | "alaska airlines" | "allegiant air" | "plus ultra líneas aéreas" | "parkwing" | "albergo - food and drinks" | "amtrak" | "italo treno" | "ilsa web" | "rail ninja" | "irish rail" | "österreichische bundesbahnen" | "rail europe" | "via rail canada" | "direct ferries" | "booking.com" | "advertising" | "best western" | "una hotels" | "unaway hotels" | "albergo - lodging" | "leonardo hotels" | "hotel mercure" | "nh hotels & resorts" | "novotel hotels" | "ac hotels" | "marriott hotels" | "sheraton hotels and resorts" | "ih hotels" | "ibis hotels" | "hyatt hotels & resorts" | "hilton hotels & resorts" | "holiday inn" | "four seasons" | "doubletree by hilton" | "crowne plaza hotels")[];
7
+ const type: isly.Type<"ryanair" | "easyjet" | "wizzair" | "aer lingus" | "air malta" | "vueling" | "jet2" | "eurowings" | "turkish air" | "tap" | "pegasus" | "royal air maroc" | "qatar air" | "blue island" | "klm" | "iberia" | "emirates" | "aegean airlines" | "tui" | "united airlines" | "cathay pacific airlines" | "air serbia" | "copa air" | "bamboo airways" | "latam airlines" | "flydubai" | "condor" | "transavia" | "austrian air" | "alitalia" | "apg airlines" | "iceland air" | "flyone" | "avianca" | "brussels airlines" | "saudia" | "aeromexico" | "gulf air" | "ethiopian airlines" | "egypt air" | "albawings" | "iberojet" | "norwegian air" | "vistara" | "air greenland" | "sky express" | "air canada" | "philippine airlines" | "south african airlink" | "air benelux" | "tunisair" | "lufthansa" | "corendon airlines" | "uganda airlines" | "freebird airlines" | "kenya airway" | "kuwait air" | "british airways" | "czech airlines" | "lot polish airlines" | "volotea" | "flybe" | "bulgaria air" | "sas" | "qantas" | "air india" | "air europa" | "royal jordanian" | "virgin atlantic" | "flexflight" | "rwandair" | "hahn air" | "american air" | "pakistan international airlines" | "singapore airlines" | "delta air lines" | "croatia airlines" | "air asia" | "hawaiian airlines" | "oman air" | "etihad air" | "middle east airlines" | "logan air" | "aurigny" | "eastern airways" | "sun express" | "spirit air" | "air france" | "malaysia airlines" | "finnair" | "swiss air" | "air china" | "ana air" | "ae bsp" | "thai airways" | "jet blue" | "westjet" | "aerolineas" | "air seoul" | "azerbaijan airlines" | "air dolomiti" | "bangkok airways" | "china airlines" | "china eastern airlines" | "eva air" | "jetstar airways" | "km malta airlines" | "ita airways" | "china southern airlines" | "world2fly" | "sata denmark" | "air baltic" | "ajet" | "flynorse" | "hainan air" | "sichuan airlines" | "korean air" | "gol airlines" | "azul brazilian airlines" | "flysafair" | "air mauritius" | "alaska airlines" | "allegiant air" | "plus ultra líneas aéreas" | "parkwing" | "albergo - food and drinks" | "amtrak" | "italo treno" | "ilsa web" | "rail ninja" | "irish rail" | "österreichische bundesbahnen" | "rail europe" | "via rail canada" | "direct ferries" | "booking.com" | "advertising" | "best western" | "una hotels" | "unaway hotels" | "albergo - lodging" | "leonardo hotels" | "hotel mercure" | "nh hotels & resorts" | "novotel hotels" | "ac hotels" | "marriott hotels" | "sheraton hotels and resorts" | "ih hotels" | "ibis hotels" | "hyatt hotels & resorts" | "hilton hotels & resorts" | "holiday inn" | "four seasons" | "doubletree by hilton" | "crowne plaza hotels">;
8
+ const type2: isly2.String<"ryanair" | "easyjet" | "wizzair" | "aer lingus" | "air malta" | "vueling" | "jet2" | "eurowings" | "turkish air" | "tap" | "pegasus" | "royal air maroc" | "qatar air" | "blue island" | "klm" | "iberia" | "emirates" | "aegean airlines" | "tui" | "united airlines" | "cathay pacific airlines" | "air serbia" | "copa air" | "bamboo airways" | "latam airlines" | "flydubai" | "condor" | "transavia" | "austrian air" | "alitalia" | "apg airlines" | "iceland air" | "flyone" | "avianca" | "brussels airlines" | "saudia" | "aeromexico" | "gulf air" | "ethiopian airlines" | "egypt air" | "albawings" | "iberojet" | "norwegian air" | "vistara" | "air greenland" | "sky express" | "air canada" | "philippine airlines" | "south african airlink" | "air benelux" | "tunisair" | "lufthansa" | "corendon airlines" | "uganda airlines" | "freebird airlines" | "kenya airway" | "kuwait air" | "british airways" | "czech airlines" | "lot polish airlines" | "volotea" | "flybe" | "bulgaria air" | "sas" | "qantas" | "air india" | "air europa" | "royal jordanian" | "virgin atlantic" | "flexflight" | "rwandair" | "hahn air" | "american air" | "pakistan international airlines" | "singapore airlines" | "delta air lines" | "croatia airlines" | "air asia" | "hawaiian airlines" | "oman air" | "etihad air" | "middle east airlines" | "logan air" | "aurigny" | "eastern airways" | "sun express" | "spirit air" | "air france" | "malaysia airlines" | "finnair" | "swiss air" | "air china" | "ana air" | "ae bsp" | "thai airways" | "jet blue" | "westjet" | "aerolineas" | "air seoul" | "azerbaijan airlines" | "air dolomiti" | "bangkok airways" | "china airlines" | "china eastern airlines" | "eva air" | "jetstar airways" | "km malta airlines" | "ita airways" | "china southern airlines" | "world2fly" | "sata denmark" | "air baltic" | "ajet" | "flynorse" | "hainan air" | "sichuan airlines" | "korean air" | "gol airlines" | "azul brazilian airlines" | "flysafair" | "air mauritius" | "alaska airlines" | "allegiant air" | "plus ultra líneas aéreas" | "parkwing" | "albergo - food and drinks" | "amtrak" | "italo treno" | "ilsa web" | "rail ninja" | "irish rail" | "österreichische bundesbahnen" | "rail europe" | "via rail canada" | "direct ferries" | "booking.com" | "advertising" | "best western" | "una hotels" | "unaway hotels" | "albergo - lodging" | "leonardo hotels" | "hotel mercure" | "nh hotels & resorts" | "novotel hotels" | "ac hotels" | "marriott hotels" | "sheraton hotels and resorts" | "ih hotels" | "ibis hotels" | "hyatt hotels & resorts" | "hilton hotels & resorts" | "holiday inn" | "four seasons" | "doubletree by hilton" | "crowne plaza hotels">;
15
9
  function check(merchant: Merchant, transaction: Transaction.Creatable.CardTransaction | Transaction.PreTransaction.Authorization): boolean;
16
10
  }