@pax2pay/model-banking 0.1.509 → 0.1.510

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 (71) hide show
  1. package/User/Access/Permission.ts +47 -0
  2. package/User/Access/index.ts +19 -0
  3. package/User/Identity.ts +32 -0
  4. package/User/JWT/Payload.ts +56 -0
  5. package/User/JWT/Signer.ts +39 -0
  6. package/User/JWT/index.ts +57 -0
  7. package/User/Me.ts +15 -0
  8. package/User/Password.ts +43 -0
  9. package/User/index.ts +68 -0
  10. package/dist/cjs/User/Access/Permission.d.ts +20 -0
  11. package/dist/cjs/User/Access/Permission.js +47 -0
  12. package/dist/cjs/User/Access/Permission.js.map +1 -0
  13. package/dist/cjs/User/Access/index.d.ts +11 -0
  14. package/dist/cjs/User/Access/index.js +16 -0
  15. package/dist/cjs/User/Access/index.js.map +1 -0
  16. package/dist/cjs/User/Identity.d.ts +16 -0
  17. package/dist/cjs/User/Identity.js +32 -0
  18. package/dist/cjs/User/Identity.js.map +1 -0
  19. package/dist/cjs/User/JWT/Payload.d.ts +43 -0
  20. package/dist/cjs/User/JWT/Payload.js +42 -0
  21. package/dist/cjs/User/JWT/Payload.js.map +1 -0
  22. package/dist/cjs/User/JWT/Signer.d.ts +23 -0
  23. package/dist/cjs/User/JWT/Signer.js +39 -0
  24. package/dist/cjs/User/JWT/Signer.js.map +1 -0
  25. package/dist/cjs/User/JWT/index.d.ts +25 -0
  26. package/dist/cjs/User/JWT/index.js +59 -0
  27. package/dist/cjs/User/JWT/index.js.map +1 -0
  28. package/dist/cjs/User/Me.d.ts +9 -0
  29. package/dist/cjs/User/Me.js +14 -0
  30. package/dist/cjs/User/Me.js.map +1 -0
  31. package/dist/cjs/User/Password.d.ts +20 -0
  32. package/dist/cjs/User/Password.js +44 -0
  33. package/dist/cjs/User/Password.js.map +1 -0
  34. package/dist/cjs/User/index.d.ts +46 -0
  35. package/dist/cjs/User/index.js +54 -0
  36. package/dist/cjs/User/index.js.map +1 -0
  37. package/dist/cjs/pax2pay.d.ts +2 -1
  38. package/dist/cjs/pax2pay.js +5 -3
  39. package/dist/cjs/pax2pay.js.map +1 -1
  40. package/dist/mjs/User/Access/Permission.d.ts +20 -0
  41. package/dist/mjs/User/Access/Permission.js +44 -0
  42. package/dist/mjs/User/Access/Permission.js.map +1 -0
  43. package/dist/mjs/User/Access/index.d.ts +11 -0
  44. package/dist/mjs/User/Access/index.js +13 -0
  45. package/dist/mjs/User/Access/index.js.map +1 -0
  46. package/dist/mjs/User/Identity.d.ts +16 -0
  47. package/dist/mjs/User/Identity.js +28 -0
  48. package/dist/mjs/User/Identity.js.map +1 -0
  49. package/dist/mjs/User/JWT/Payload.d.ts +43 -0
  50. package/dist/mjs/User/JWT/Payload.js +39 -0
  51. package/dist/mjs/User/JWT/Payload.js.map +1 -0
  52. package/dist/mjs/User/JWT/Signer.d.ts +23 -0
  53. package/dist/mjs/User/JWT/Signer.js +35 -0
  54. package/dist/mjs/User/JWT/Signer.js.map +1 -0
  55. package/dist/mjs/User/JWT/index.d.ts +25 -0
  56. package/dist/mjs/User/JWT/index.js +55 -0
  57. package/dist/mjs/User/JWT/index.js.map +1 -0
  58. package/dist/mjs/User/Me.d.ts +9 -0
  59. package/dist/mjs/User/Me.js +11 -0
  60. package/dist/mjs/User/Me.js.map +1 -0
  61. package/dist/mjs/User/Password.d.ts +20 -0
  62. package/dist/mjs/User/Password.js +41 -0
  63. package/dist/mjs/User/Password.js.map +1 -0
  64. package/dist/mjs/User/index.d.ts +46 -0
  65. package/dist/mjs/User/index.js +51 -0
  66. package/dist/mjs/User/index.js.map +1 -0
  67. package/dist/mjs/pax2pay.d.ts +2 -1
  68. package/dist/mjs/pax2pay.js +2 -1
  69. package/dist/mjs/pax2pay.js.map +1 -1
  70. package/package.json +1 -1
  71. package/pax2pay.ts +2 -1
@@ -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
+ }
@@ -0,0 +1,20 @@
1
+ import { isly } from "isly";
2
+ export type Permission = Partial<Record<Permission.Collection, Permission.Level>>;
3
+ export declare namespace Permission {
4
+ type Realm = Omit<Permission, "user">;
5
+ type Global = Pick<Permission, "user">;
6
+ function check(constraint: Permission, privilege: Permission): boolean;
7
+ type Level = typeof Level.values[number];
8
+ namespace Level {
9
+ const values: readonly ["read", "write", "developer", "admin"];
10
+ const type: isly.Type<"admin" | "read" | "write" | "developer">;
11
+ function get(level: Level | undefined): number;
12
+ const value: Record<Level, number>;
13
+ }
14
+ type Collection = typeof Collection.values[number];
15
+ namespace Collection {
16
+ const values: readonly ["account", "card", "log", "operation", "organization", "rule", "settlement", "transaction", "treasury", "user", "*"];
17
+ const type: isly.Type<"rule" | "card" | "transaction" | "account" | "settlement" | "organization" | "log" | "user" | "operation" | "treasury" | "*">;
18
+ }
19
+ const type: isly.Type<Partial<Record<"rule" | "card" | "transaction" | "account" | "settlement" | "organization" | "log" | "user" | "operation" | "treasury" | "*", "admin" | "read" | "write" | "developer">>>;
20
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Permission = void 0;
4
+ const isly_1 = require("isly");
5
+ const typedly_1 = require("typedly");
6
+ var Permission;
7
+ (function (Permission) {
8
+ function check(constraint, privilege) {
9
+ return typedly_1.typedly.Object.entries(constraint).every(([collection, level]) => Permission.Level.get(privilege[collection]) >= Permission.Level.get(level) ||
10
+ Permission.Level.get(privilege["*"]) >= Permission.Level.get(level));
11
+ }
12
+ Permission.check = check;
13
+ let Level;
14
+ (function (Level) {
15
+ Level.values = ["read", "write", "developer", "admin"];
16
+ Level.type = isly_1.isly.string(Level.values);
17
+ function get(level) {
18
+ return level ? Level.value[level] : 0;
19
+ }
20
+ Level.get = get;
21
+ Level.value = {
22
+ read: 1,
23
+ write: 2,
24
+ developer: 3,
25
+ admin: 4,
26
+ };
27
+ })(Level = Permission.Level || (Permission.Level = {}));
28
+ let Collection;
29
+ (function (Collection) {
30
+ Collection.values = [
31
+ "account",
32
+ "card",
33
+ "log",
34
+ "operation",
35
+ "organization",
36
+ "rule",
37
+ "settlement",
38
+ "transaction",
39
+ "treasury",
40
+ "user",
41
+ "*",
42
+ ];
43
+ Collection.type = isly_1.isly.string(Collection.values);
44
+ })(Collection = Permission.Collection || (Permission.Collection = {}));
45
+ Permission.type = isly_1.isly.record(Collection.type, Level.type);
46
+ })(Permission || (exports.Permission = Permission = {}));
47
+ //# sourceMappingURL=Permission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Permission.js","sourceRoot":"","sources":["../../../../User/Access/Permission.ts"],"names":[],"mappings":";;;AAAA,+BAA2B;AAC3B,qCAAiC;AAGjC,IAAiB,UAAU,CA0C1B;AA1CD,WAAiB,UAAU;IAG1B,SAAgB,KAAK,CAAC,UAAsB,EAAE,SAAqB;QAClE,OAAO,iBAAO,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,KAAK,CAC9C,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,EAAE,CACvB,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YAC1E,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CACpE,CAAA;IACF,CAAC;IANe,gBAAK,QAMpB,CAAA;IAED,IAAiB,KAAK,CAYrB;IAZD,WAAiB,KAAK;QACR,YAAM,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAU,CAAA;QACzD,UAAI,GAAG,WAAI,CAAC,MAAM,CAAC,MAAA,MAAM,CAAC,CAAA;QACvC,SAAgB,GAAG,CAAC,KAAwB;YAC3C,OAAO,KAAK,CAAC,CAAC,CAAC,MAAA,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAChC,CAAC;QAFe,SAAG,MAElB,CAAA;QACY,WAAK,GAA0B;YAC3C,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,CAAC;YACR,SAAS,EAAE,CAAC;YACZ,KAAK,EAAE,CAAC;SACC,CAAA;IACX,CAAC,EAZgB,KAAK,GAAL,gBAAK,KAAL,gBAAK,QAYrB;IAED,IAAiB,UAAU,CAe1B;IAfD,WAAiB,UAAU;QACb,iBAAM,GAAG;YACrB,SAAS;YACT,MAAM;YACN,KAAK;YACL,WAAW;YACX,cAAc;YACd,MAAM;YACN,YAAY;YACZ,aAAa;YACb,UAAU;YACV,MAAM;YACN,GAAG;SACM,CAAA;QACG,eAAI,GAAG,WAAI,CAAC,MAAM,CAAC,WAAA,MAAM,CAAC,CAAA;IACxC,CAAC,EAfgB,UAAU,GAAV,qBAAU,KAAV,qBAAU,QAe1B;IACY,eAAI,GAAG,WAAI,CAAC,MAAM,CAAa,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;AACzE,CAAC,EA1CgB,UAAU,0BAAV,UAAU,QA0C1B"}
@@ -0,0 +1,11 @@
1
+ import { Permission as AccessPermission } from "./Permission";
2
+ export interface Access {
3
+ uk?: Access.Permission.Realm;
4
+ eea?: Access.Permission.Realm;
5
+ test?: Access.Permission.Realm;
6
+ "*"?: Access.Permission.Global;
7
+ }
8
+ export declare namespace Access {
9
+ export import Permission = AccessPermission;
10
+ const type: import("isly/dist/cjs/object").IslyObject<object, object>;
11
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Access = void 0;
4
+ const isly_1 = require("isly");
5
+ const Permission_1 = require("./Permission");
6
+ var Access;
7
+ (function (Access) {
8
+ Access.Permission = Permission_1.Permission;
9
+ Access.type = isly_1.isly.object({
10
+ uk: Access.Permission.type.optional(),
11
+ eea: Access.Permission.type.optional(),
12
+ test: Access.Permission.type.optional(),
13
+ "*": isly_1.isly.object({ user: Access.Permission.Level.type.optional() }).optional(),
14
+ });
15
+ })(Access || (exports.Access = Access = {}));
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../User/Access/index.ts"],"names":[],"mappings":";;;AAAA,+BAA2B;AAC3B,6CAA6D;AAS7D,IAAiB,MAAM,CAQtB;AARD,WAAiB,MAAM;IACR,iBAAU,GAAG,uBAAgB,CAAA;IAC9B,WAAI,GAAG,WAAI,CAAC,MAAM,CAAC;QAC/B,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE;QACrC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE;QACtC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE;QACvC,GAAG,EAAE,WAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;KAC9E,CAAC,CAAA;AACH,CAAC,EARgB,MAAM,sBAAN,MAAM,QAQtB"}
@@ -0,0 +1,16 @@
1
+ import { gracely } from "gracely";
2
+ import { Realm } from "../Realm";
3
+ import { Access } from "./Access";
4
+ import { JWT } from "./JWT";
5
+ export declare class Identity {
6
+ readonly payload: JWT.Payload;
7
+ private readonly jwt;
8
+ get realm(): Realm;
9
+ constructor(payload: JWT.Payload, jwt: string);
10
+ authenticate(constraint: Access.Permission | Access.Permission[]): Identity | gracely.Error;
11
+ static open(authorization: string | undefined, options: {
12
+ whitelist?: JWT.Whitelist;
13
+ key?: string;
14
+ }): Promise<Identity | gracely.Error>;
15
+ }
16
+ export declare namespace Identity { }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Identity = void 0;
4
+ const gracely_1 = require("gracely");
5
+ const Access_1 = require("./Access");
6
+ const JWT_1 = require("./JWT");
7
+ class Identity {
8
+ payload;
9
+ jwt;
10
+ get realm() {
11
+ return this.payload.realm;
12
+ }
13
+ constructor(payload, jwt) {
14
+ this.payload = payload;
15
+ this.jwt = jwt;
16
+ }
17
+ authenticate(constraint) {
18
+ let allowed;
19
+ if (Array.isArray(constraint))
20
+ allowed = constraint.some(c => this.authenticate(c));
21
+ else
22
+ allowed = Access_1.Access.Permission.check(constraint, this.payload.permission);
23
+ return allowed ? this : gracely_1.gracely.client.forbidden();
24
+ }
25
+ static async open(authorization, options) {
26
+ const jwt = authorization?.startsWith("Bearer ") ? authorization.replace("Bearer ", "") : undefined;
27
+ const payload = jwt ? await JWT_1.JWT.open({ public: options.key }, options.whitelist).verify(jwt) : undefined;
28
+ return jwt && payload ? new Identity(payload, jwt) : gracely_1.gracely.client.unauthorized();
29
+ }
30
+ }
31
+ exports.Identity = Identity;
32
+ //# sourceMappingURL=Identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Identity.js","sourceRoot":"","sources":["../../../User/Identity.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AAGjC,qCAAiC;AACjC,+BAA2B;AAE3B,MAAa,QAAQ;IAIQ;IAAuC;IAHnE,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAA;IAC1B,CAAC;IACD,YAA4B,OAAoB,EAAmB,GAAW;QAAlD,YAAO,GAAP,OAAO,CAAa;QAAmB,QAAG,GAAH,GAAG,CAAQ;IAAG,CAAC;IAElF,YAAY,CAAC,UAAmD;QAC/D,IAAI,OAAgB,CAAA;QACpB,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;YAC5B,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA;;YAEpD,OAAO,GAAG,eAAM,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QACvE,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAA;IACnD,CAAC;IAGD,MAAM,CAAC,KAAK,CAAC,IAAI,CAChB,aAAiC,EACjC,OAAoD;QAEpD,MAAM,GAAG,GAAG,aAAa,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACnG,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,SAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACxG,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAA;IACnF,CAAC;CACD;AAxBD,4BAwBC"}
@@ -0,0 +1,43 @@
1
+ import { authly } from "authly";
2
+ import { isly } from "isly";
3
+ import { Realm } from "../../Realm";
4
+ import { Access } from "../Access";
5
+ export type Payload = Payload.LongTerm | Payload.ShortTerm;
6
+ export declare namespace Payload {
7
+ interface Creatable {
8
+ sub: string;
9
+ permission: Access.Permission;
10
+ realm: Realm;
11
+ }
12
+ namespace Creatable {
13
+ const type: import("isly/dist/cjs/object").IslyObject<Creatable, object>;
14
+ }
15
+ interface Base extends authly.Payload {
16
+ aud: string;
17
+ iat: number;
18
+ iss: string;
19
+ sub: string;
20
+ permission: Access.Permission;
21
+ realm: Realm;
22
+ }
23
+ namespace Base {
24
+ const type: import("isly/dist/cjs/object").IslyObject<Payload, object>;
25
+ }
26
+ interface LongTerm extends Base {
27
+ id: string;
28
+ }
29
+ namespace LongTerm {
30
+ const type: import("isly/dist/cjs/object").IslyObject<LongTerm, Payload>;
31
+ }
32
+ interface ShortTerm extends Base {
33
+ exp: number;
34
+ }
35
+ namespace ShortTerm {
36
+ const type: import("isly/dist/cjs/object").IslyObject<ShortTerm, Payload>;
37
+ }
38
+ const configuration: {
39
+ aud: string;
40
+ iss: string;
41
+ };
42
+ const type: isly.Type<Payload>;
43
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Payload = void 0;
4
+ const isly_1 = require("isly");
5
+ const Realm_1 = require("../../Realm");
6
+ const Access_1 = require("../Access");
7
+ var Payload;
8
+ (function (Payload) {
9
+ let Creatable;
10
+ (function (Creatable) {
11
+ Creatable.type = isly_1.isly.object({
12
+ sub: isly_1.isly.string(),
13
+ permission: Access_1.Access.Permission.type,
14
+ realm: Realm_1.Realm.type,
15
+ });
16
+ })(Creatable = Payload.Creatable || (Payload.Creatable = {}));
17
+ let Base;
18
+ (function (Base) {
19
+ Base.type = isly_1.isly.object({
20
+ aud: isly_1.isly.string(),
21
+ iat: isly_1.isly.number(),
22
+ iss: isly_1.isly.string(),
23
+ sub: isly_1.isly.string(),
24
+ permission: Access_1.Access.Permission.type,
25
+ realm: Realm_1.Realm.type,
26
+ });
27
+ })(Base = Payload.Base || (Payload.Base = {}));
28
+ let LongTerm;
29
+ (function (LongTerm) {
30
+ LongTerm.type = Base.type.extend({ id: isly_1.isly.string() });
31
+ })(LongTerm = Payload.LongTerm || (Payload.LongTerm = {}));
32
+ let ShortTerm;
33
+ (function (ShortTerm) {
34
+ ShortTerm.type = Base.type.extend({ exp: isly_1.isly.number() });
35
+ })(ShortTerm = Payload.ShortTerm || (Payload.ShortTerm = {}));
36
+ Payload.configuration = {
37
+ aud: "https://banking.pax2pay.app",
38
+ iss: "pax2pay",
39
+ };
40
+ Payload.type = isly_1.isly.union(LongTerm.type, ShortTerm.type);
41
+ })(Payload || (exports.Payload = Payload = {}));
42
+ //# sourceMappingURL=Payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Payload.js","sourceRoot":"","sources":["../../../../User/JWT/Payload.ts"],"names":[],"mappings":";;;AACA,+BAA2B;AAC3B,uCAAmC;AACnC,sCAAkC;AAGlC,IAAiB,OAAO,CAiDvB;AAjDD,WAAiB,OAAO;IAMvB,IAAiB,SAAS,CAMzB;IAND,WAAiB,SAAS;QACZ,cAAI,GAAG,WAAI,CAAC,MAAM,CAAY;YAC1C,GAAG,EAAE,WAAI,CAAC,MAAM,EAAE;YAClB,UAAU,EAAE,eAAM,CAAC,UAAU,CAAC,IAAI;YAClC,KAAK,EAAE,aAAK,CAAC,IAAI;SACjB,CAAC,CAAA;IACH,CAAC,EANgB,SAAS,GAAT,iBAAS,KAAT,iBAAS,QAMzB;IASD,IAAiB,IAAI,CASpB;IATD,WAAiB,IAAI;QACP,SAAI,GAAG,WAAI,CAAC,MAAM,CAAU;YACxC,GAAG,EAAE,WAAI,CAAC,MAAM,EAAE;YAClB,GAAG,EAAE,WAAI,CAAC,MAAM,EAAE;YAClB,GAAG,EAAE,WAAI,CAAC,MAAM,EAAE;YAClB,GAAG,EAAE,WAAI,CAAC,MAAM,EAAE;YAClB,UAAU,EAAE,eAAM,CAAC,UAAU,CAAC,IAAI;YAClC,KAAK,EAAE,aAAK,CAAC,IAAI;SACjB,CAAC,CAAA;IACH,CAAC,EATgB,IAAI,GAAJ,YAAI,KAAJ,YAAI,QASpB;IAID,IAAiB,QAAQ,CAExB;IAFD,WAAiB,QAAQ;QACX,aAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAW,EAAE,EAAE,EAAE,WAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACtE,CAAC,EAFgB,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAExB;IAID,IAAiB,SAAS,CAEzB;IAFD,WAAiB,SAAS;QACZ,cAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAY,EAAE,GAAG,EAAE,WAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACxE,CAAC,EAFgB,SAAS,GAAT,iBAAS,KAAT,iBAAS,QAEzB;IAEY,qBAAa,GAAG;QAC5B,GAAG,EAAE,6BAA6B;QAClC,GAAG,EAAE,SAAS;KACd,CAAA;IACY,YAAI,GAAG,WAAI,CAAC,KAAK,CAAU,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAA;AACvE,CAAC,EAjDgB,OAAO,uBAAP,OAAO,QAiDvB"}
@@ -0,0 +1,23 @@
1
+ import { authly } from "authly";
2
+ import { Payload } from "./Payload";
3
+ export declare class Signer {
4
+ private readonly key?;
5
+ constructor(key?: {
6
+ public?: string;
7
+ private?: string;
8
+ } | undefined);
9
+ sign(data: Payload.Creatable, duration?: number | "infinite"): Promise<string | undefined>;
10
+ static open(key?: {
11
+ public?: string;
12
+ private?: string;
13
+ }): Signer;
14
+ }
15
+ export declare namespace Signer {
16
+ function create<T extends authly.Payload>(options: {
17
+ key?: {
18
+ public?: string;
19
+ private?: string;
20
+ };
21
+ duration?: number;
22
+ }): authly.Issuer<T> | undefined;
23
+ }