@sphereon/ssi-sdk.data-store 0.36.1-next.119 → 0.36.1-next.129
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.
- package/dist/index.cjs +477 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +492 -117
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
- package/src/__tests__/issuanceBranding.entities.test.ts +1 -1
- package/src/__tests__/issuanceBranding.store.test.ts +310 -0
- package/src/contact/ContactStore.ts +14 -2
- package/src/entities/issuanceBranding/CredentialBrandingEntity.ts +44 -1
- package/src/entities/issuanceBranding/CredentialLocaleBrandingEntity.ts +64 -1
- package/src/entities/issuanceBranding/IssuerLocaleBrandingEntity.ts +63 -1
- package/src/issuanceBranding/IssuanceBrandingStore.ts +45 -6
- package/src/migrations/generic/15-AddBrandingState.ts +64 -0
- package/src/migrations/generic/index.ts +6 -1
- package/src/migrations/postgres/1766000000000-AddBrandingState.ts +15 -0
- package/src/migrations/sqlite/1766000000000-AddBrandingState.ts +87 -0
- package/src/utils/issuanceBranding/HashUtils.ts +30 -0
- package/src/utils/issuanceBranding/MappingUtils.ts +21 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/ssi-sdk.data-store",
|
|
3
|
-
"version": "0.36.1-next.
|
|
3
|
+
"version": "0.36.1-next.129+2a4f4386",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@sphereon/kmp-mdoc-core": "0.2.0-SNAPSHOT.26",
|
|
30
30
|
"@sphereon/pex": "5.0.0-unstable.28",
|
|
31
|
-
"@sphereon/ssi-sdk-ext.did-utils": "0.36.1-next.
|
|
32
|
-
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.36.1-next.
|
|
33
|
-
"@sphereon/ssi-sdk.agent-config": "0.36.1-next.
|
|
34
|
-
"@sphereon/ssi-sdk.core": "0.36.1-next.
|
|
35
|
-
"@sphereon/ssi-sdk.data-store-types": "0.36.1-next.
|
|
36
|
-
"@sphereon/ssi-types": "0.36.1-next.
|
|
31
|
+
"@sphereon/ssi-sdk-ext.did-utils": "0.36.1-next.129+2a4f4386",
|
|
32
|
+
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.36.1-next.129+2a4f4386",
|
|
33
|
+
"@sphereon/ssi-sdk.agent-config": "0.36.1-next.129+2a4f4386",
|
|
34
|
+
"@sphereon/ssi-sdk.core": "0.36.1-next.129+2a4f4386",
|
|
35
|
+
"@sphereon/ssi-sdk.data-store-types": "0.36.1-next.129+2a4f4386",
|
|
36
|
+
"@sphereon/ssi-types": "0.36.1-next.129+2a4f4386",
|
|
37
37
|
"@veramo/core": "4.2.0",
|
|
38
38
|
"@veramo/utils": "4.2.0",
|
|
39
39
|
"blakejs": "^1.2.1",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"PostgreSQL",
|
|
67
67
|
"Contact Store"
|
|
68
68
|
],
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "2a4f43863a1544f53c63485daee40bcb2abbfa81"
|
|
70
70
|
}
|
|
@@ -823,7 +823,7 @@ describe('Database entities tests', (): void => {
|
|
|
823
823
|
}
|
|
824
824
|
|
|
825
825
|
const issuerLocaleBrandingEntity: IssuerLocaleBrandingEntity = issuerLocaleBrandingEntityFrom(localeBranding)
|
|
826
|
-
const fromDb: IssuerLocaleBrandingEntity = await dbConnection.getRepository(
|
|
826
|
+
const fromDb: IssuerLocaleBrandingEntity = await dbConnection.getRepository(IssuerLocaleBrandingEntity).save(issuerLocaleBrandingEntity)
|
|
827
827
|
|
|
828
828
|
expect(fromDb).toBeDefined()
|
|
829
829
|
expect(fromDb?.alias).toEqual(localeBranding.alias)
|
|
@@ -1884,4 +1884,314 @@ describe('Issuance branding store tests', (): void => {
|
|
|
1884
1884
|
expect(result?.localeBranding[0].background!.image!.alt).toBeUndefined()
|
|
1885
1885
|
expect(result?.localeBranding[0].text!.color).toBeUndefined()
|
|
1886
1886
|
})
|
|
1887
|
+
|
|
1888
|
+
// State-related tests
|
|
1889
|
+
|
|
1890
|
+
it('should populate state field when adding credential branding', async (): Promise<void> => {
|
|
1891
|
+
const credentialBranding: IBasicCredentialBranding = {
|
|
1892
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
1893
|
+
vcHash: 'vcHash',
|
|
1894
|
+
localeBranding: [
|
|
1895
|
+
{
|
|
1896
|
+
alias: 'credentialTypeAlias',
|
|
1897
|
+
locale: 'en-US',
|
|
1898
|
+
},
|
|
1899
|
+
],
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
const result: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding)
|
|
1903
|
+
|
|
1904
|
+
expect(result).toBeDefined()
|
|
1905
|
+
expect(result.state).toBeDefined()
|
|
1906
|
+
expect(typeof result.state).toBe('string')
|
|
1907
|
+
expect(result.state.length).toBeGreaterThan(0)
|
|
1908
|
+
expect(result.localeBranding[0].state).toBeDefined()
|
|
1909
|
+
expect(typeof result.localeBranding[0].state).toBe('string')
|
|
1910
|
+
expect(result.localeBranding[0].state.length).toBeGreaterThan(0)
|
|
1911
|
+
})
|
|
1912
|
+
|
|
1913
|
+
it('should generate different states for different credential brandings', async (): Promise<void> => {
|
|
1914
|
+
const credentialBranding1: IBasicCredentialBranding = {
|
|
1915
|
+
issuerCorrelationId: 'issuerCorrelationId1',
|
|
1916
|
+
vcHash: 'vcHash1',
|
|
1917
|
+
localeBranding: [
|
|
1918
|
+
{
|
|
1919
|
+
alias: 'credentialTypeAlias1',
|
|
1920
|
+
locale: 'en-US',
|
|
1921
|
+
},
|
|
1922
|
+
],
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
const credentialBranding2: IBasicCredentialBranding = {
|
|
1926
|
+
issuerCorrelationId: 'issuerCorrelationId2',
|
|
1927
|
+
vcHash: 'vcHash2',
|
|
1928
|
+
localeBranding: [
|
|
1929
|
+
{
|
|
1930
|
+
alias: 'credentialTypeAlias2',
|
|
1931
|
+
locale: 'en-US',
|
|
1932
|
+
},
|
|
1933
|
+
],
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
const result1: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding1)
|
|
1937
|
+
const result2: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding2)
|
|
1938
|
+
|
|
1939
|
+
expect(result1.state).toBeDefined()
|
|
1940
|
+
expect(result2.state).toBeDefined()
|
|
1941
|
+
expect(result1.state).not.toEqual(result2.state)
|
|
1942
|
+
expect(result1.localeBranding[0].state).not.toEqual(result2.localeBranding[0].state)
|
|
1943
|
+
})
|
|
1944
|
+
|
|
1945
|
+
it('should keep same state when credential branding content does not change', async (): Promise<void> => {
|
|
1946
|
+
const credentialBranding: IBasicCredentialBranding = {
|
|
1947
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
1948
|
+
vcHash: 'vcHash',
|
|
1949
|
+
localeBranding: [
|
|
1950
|
+
{
|
|
1951
|
+
alias: 'credentialTypeAlias',
|
|
1952
|
+
locale: 'en-US',
|
|
1953
|
+
description: 'Description',
|
|
1954
|
+
},
|
|
1955
|
+
],
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
const original: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding)
|
|
1959
|
+
const originalState: string = original.state
|
|
1960
|
+
const originalLocaleState: string = original.localeBranding[0].state
|
|
1961
|
+
|
|
1962
|
+
const retrieved: Array<ICredentialBranding> = await issuanceBrandingStore.getCredentialBranding({ filter: [{ id: original.id }] })
|
|
1963
|
+
|
|
1964
|
+
expect(retrieved).toBeDefined()
|
|
1965
|
+
expect(retrieved.length).toEqual(1)
|
|
1966
|
+
expect(retrieved[0].state).toEqual(originalState)
|
|
1967
|
+
expect(retrieved[0].localeBranding[0].state).toEqual(originalLocaleState)
|
|
1968
|
+
})
|
|
1969
|
+
|
|
1970
|
+
it('should filter credential branding by knownStates when all states match', async (): Promise<void> => {
|
|
1971
|
+
const credentialBranding: IBasicCredentialBranding = {
|
|
1972
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
1973
|
+
vcHash: 'vcHash',
|
|
1974
|
+
localeBranding: [
|
|
1975
|
+
{
|
|
1976
|
+
alias: 'credentialTypeAlias',
|
|
1977
|
+
locale: 'en-US',
|
|
1978
|
+
},
|
|
1979
|
+
],
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
const saved: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding)
|
|
1983
|
+
const knownStates: Record<string, string> = {
|
|
1984
|
+
[saved.id]: saved.state,
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
const result: Array<ICredentialBranding> = await issuanceBrandingStore.getCredentialBranding({ knownStates })
|
|
1988
|
+
|
|
1989
|
+
expect(result.length).toEqual(0)
|
|
1990
|
+
})
|
|
1991
|
+
|
|
1992
|
+
it('should return credential branding when knownStates differs', async (): Promise<void> => {
|
|
1993
|
+
const credentialBranding: IBasicCredentialBranding = {
|
|
1994
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
1995
|
+
vcHash: 'vcHash',
|
|
1996
|
+
localeBranding: [
|
|
1997
|
+
{
|
|
1998
|
+
alias: 'credentialTypeAlias',
|
|
1999
|
+
locale: 'en-US',
|
|
2000
|
+
},
|
|
2001
|
+
],
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
const saved: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding)
|
|
2005
|
+
const knownStates: Record<string, string> = {
|
|
2006
|
+
[saved.id]: 'differentState',
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
const result: Array<ICredentialBranding> = await issuanceBrandingStore.getCredentialBranding({ knownStates })
|
|
2010
|
+
|
|
2011
|
+
expect(result.length).toEqual(1)
|
|
2012
|
+
expect(result[0].id).toEqual(saved.id)
|
|
2013
|
+
})
|
|
2014
|
+
|
|
2015
|
+
it('should return credential branding when not in knownStates map', async (): Promise<void> => {
|
|
2016
|
+
const credentialBranding: IBasicCredentialBranding = {
|
|
2017
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
2018
|
+
vcHash: 'vcHash',
|
|
2019
|
+
localeBranding: [
|
|
2020
|
+
{
|
|
2021
|
+
alias: 'credentialTypeAlias',
|
|
2022
|
+
locale: 'en-US',
|
|
2023
|
+
},
|
|
2024
|
+
],
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
const saved: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding)
|
|
2028
|
+
const knownStates: Record<string, string> = {}
|
|
2029
|
+
|
|
2030
|
+
const result: Array<ICredentialBranding> = await issuanceBrandingStore.getCredentialBranding({ knownStates })
|
|
2031
|
+
|
|
2032
|
+
expect(result.length).toEqual(1)
|
|
2033
|
+
expect(result[0].id).toEqual(saved.id)
|
|
2034
|
+
})
|
|
2035
|
+
|
|
2036
|
+
it('should filter multiple credential brandings correctly with knownStates', async (): Promise<void> => {
|
|
2037
|
+
const credentialBranding1: IBasicCredentialBranding = {
|
|
2038
|
+
issuerCorrelationId: 'issuerCorrelationId1',
|
|
2039
|
+
vcHash: 'vcHash1',
|
|
2040
|
+
localeBranding: [
|
|
2041
|
+
{
|
|
2042
|
+
alias: 'credentialTypeAlias1',
|
|
2043
|
+
locale: 'en-US',
|
|
2044
|
+
},
|
|
2045
|
+
],
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
const credentialBranding2: IBasicCredentialBranding = {
|
|
2049
|
+
issuerCorrelationId: 'issuerCorrelationId2',
|
|
2050
|
+
vcHash: 'vcHash2',
|
|
2051
|
+
localeBranding: [
|
|
2052
|
+
{
|
|
2053
|
+
alias: 'credentialTypeAlias2',
|
|
2054
|
+
locale: 'en-US',
|
|
2055
|
+
},
|
|
2056
|
+
],
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
const credentialBranding3: IBasicCredentialBranding = {
|
|
2060
|
+
issuerCorrelationId: 'issuerCorrelationId3',
|
|
2061
|
+
vcHash: 'vcHash3',
|
|
2062
|
+
localeBranding: [
|
|
2063
|
+
{
|
|
2064
|
+
alias: 'credentialTypeAlias3',
|
|
2065
|
+
locale: 'en-US',
|
|
2066
|
+
},
|
|
2067
|
+
],
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
const saved1: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding1)
|
|
2071
|
+
const saved2: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding2)
|
|
2072
|
+
const saved3: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding3)
|
|
2073
|
+
|
|
2074
|
+
const knownStates: Record<string, string> = {
|
|
2075
|
+
[saved1.id]: saved1.state,
|
|
2076
|
+
[saved2.id]: 'differentState',
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
const result: Array<ICredentialBranding> = await issuanceBrandingStore.getCredentialBranding({ knownStates })
|
|
2080
|
+
|
|
2081
|
+
expect(result.length).toEqual(2)
|
|
2082
|
+
const resultIds: Array<string> = result.map((r: ICredentialBranding) => r.id)
|
|
2083
|
+
expect(resultIds).toContain(saved2.id)
|
|
2084
|
+
expect(resultIds).toContain(saved3.id)
|
|
2085
|
+
expect(resultIds).not.toContain(saved1.id)
|
|
2086
|
+
})
|
|
2087
|
+
|
|
2088
|
+
it('should add new locale branding with state field populated', async (): Promise<void> => {
|
|
2089
|
+
const credentialBranding: IBasicCredentialBranding = {
|
|
2090
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
2091
|
+
vcHash: 'vcHash',
|
|
2092
|
+
localeBranding: [
|
|
2093
|
+
{
|
|
2094
|
+
alias: 'credentialTypeAlias',
|
|
2095
|
+
locale: 'en-US',
|
|
2096
|
+
},
|
|
2097
|
+
],
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
const saved: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding)
|
|
2101
|
+
|
|
2102
|
+
const addLocaleBrandingArgs: IAddCredentialLocaleBrandingArgs = {
|
|
2103
|
+
credentialBrandingId: saved.id,
|
|
2104
|
+
localeBranding: [
|
|
2105
|
+
{
|
|
2106
|
+
alias: 'credentialTypeAlias',
|
|
2107
|
+
locale: 'en-GB',
|
|
2108
|
+
},
|
|
2109
|
+
],
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
const result: ICredentialBranding = await issuanceBrandingStore.addCredentialLocaleBranding(addLocaleBrandingArgs)
|
|
2113
|
+
|
|
2114
|
+
expect(result.localeBranding.length).toEqual(2)
|
|
2115
|
+
expect(result.localeBranding[0].state).toBeDefined()
|
|
2116
|
+
expect(result.localeBranding[1].state).toBeDefined()
|
|
2117
|
+
expect(result.localeBranding[0].state).not.toEqual(result.localeBranding[1].state)
|
|
2118
|
+
})
|
|
2119
|
+
|
|
2120
|
+
it('should compute state based on locale branding claims', async (): Promise<void> => {
|
|
2121
|
+
const credentialBranding1: IBasicCredentialBranding = {
|
|
2122
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
2123
|
+
vcHash: 'vcHash1',
|
|
2124
|
+
localeBranding: [
|
|
2125
|
+
{
|
|
2126
|
+
alias: 'credentialTypeAlias',
|
|
2127
|
+
locale: 'en-US',
|
|
2128
|
+
claims: [
|
|
2129
|
+
{
|
|
2130
|
+
key: 'name',
|
|
2131
|
+
name: 'Full Name',
|
|
2132
|
+
},
|
|
2133
|
+
],
|
|
2134
|
+
},
|
|
2135
|
+
],
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
const credentialBranding2: IBasicCredentialBranding = {
|
|
2139
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
2140
|
+
vcHash: 'vcHash2',
|
|
2141
|
+
localeBranding: [
|
|
2142
|
+
{
|
|
2143
|
+
alias: 'credentialTypeAlias',
|
|
2144
|
+
locale: 'en-US',
|
|
2145
|
+
claims: [
|
|
2146
|
+
{
|
|
2147
|
+
key: 'email',
|
|
2148
|
+
name: 'Email Address',
|
|
2149
|
+
},
|
|
2150
|
+
],
|
|
2151
|
+
},
|
|
2152
|
+
],
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
const saved1: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding1)
|
|
2156
|
+
const saved2: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding2)
|
|
2157
|
+
|
|
2158
|
+
expect(saved1.localeBranding[0].state).toBeDefined()
|
|
2159
|
+
expect(saved2.localeBranding[0].state).toBeDefined()
|
|
2160
|
+
expect(saved1.localeBranding[0].state).not.toEqual(saved2.localeBranding[0].state)
|
|
2161
|
+
})
|
|
2162
|
+
|
|
2163
|
+
it('should compute deterministic state for same content', async (): Promise<void> => {
|
|
2164
|
+
const credentialBranding1: IBasicCredentialBranding = {
|
|
2165
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
2166
|
+
vcHash: 'vcHash',
|
|
2167
|
+
localeBranding: [
|
|
2168
|
+
{
|
|
2169
|
+
alias: 'credentialTypeAlias',
|
|
2170
|
+
locale: 'en-US',
|
|
2171
|
+
description: 'Test description',
|
|
2172
|
+
},
|
|
2173
|
+
],
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
const saved1: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding1)
|
|
2177
|
+
|
|
2178
|
+
await issuanceBrandingStore.removeCredentialBranding({ filter: [{ id: saved1.id }] })
|
|
2179
|
+
|
|
2180
|
+
const credentialBranding2: IBasicCredentialBranding = {
|
|
2181
|
+
issuerCorrelationId: 'issuerCorrelationId',
|
|
2182
|
+
vcHash: 'vcHash',
|
|
2183
|
+
localeBranding: [
|
|
2184
|
+
{
|
|
2185
|
+
alias: 'credentialTypeAlias',
|
|
2186
|
+
locale: 'en-US',
|
|
2187
|
+
description: 'Test description',
|
|
2188
|
+
},
|
|
2189
|
+
],
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
const saved2: ICredentialBranding = await issuanceBrandingStore.addCredentialBranding(credentialBranding2)
|
|
2193
|
+
|
|
2194
|
+
expect(saved1.state).toEqual(saved2.state)
|
|
2195
|
+
expect(saved1.localeBranding[0].state).toEqual(saved2.localeBranding[0].state)
|
|
2196
|
+
})
|
|
1887
2197
|
})
|
|
@@ -109,9 +109,21 @@ export class ContactStore extends AbstractContactStore {
|
|
|
109
109
|
const initialResult = await partyRepository.find({ select: ['id'], where: filterConditions })
|
|
110
110
|
|
|
111
111
|
// Fetch the complete entities based on the initial result IDs
|
|
112
|
-
const result = await partyRepository.find({
|
|
112
|
+
const result = await partyRepository.find({
|
|
113
|
+
where: { id: In(initialResult.map((party) => party.id)) },
|
|
114
|
+
relations: ['contact'], // Explicit load prevents eager loading issues
|
|
115
|
+
})
|
|
113
116
|
debug(`getParties() resulted in ${result.length} parties`)
|
|
114
|
-
return result
|
|
117
|
+
return result
|
|
118
|
+
.filter((party) => {
|
|
119
|
+
// Do not crash fetching the entire contacts list over one missing contact relation
|
|
120
|
+
if (!party.contact) {
|
|
121
|
+
console.warn(`party ${party.id} does not have an associated contact`)
|
|
122
|
+
return false
|
|
123
|
+
}
|
|
124
|
+
return true
|
|
125
|
+
})
|
|
126
|
+
.map(partyFrom)
|
|
115
127
|
}
|
|
116
128
|
|
|
117
129
|
addParty = async (args: AddPartyArgs): Promise<Party> => {
|
|
@@ -12,7 +12,8 @@ import {
|
|
|
12
12
|
PrimaryGeneratedColumn,
|
|
13
13
|
UpdateDateColumn,
|
|
14
14
|
} from 'typeorm'
|
|
15
|
-
import { CredentialLocaleBrandingEntity } from './CredentialLocaleBrandingEntity'
|
|
15
|
+
import { CredentialLocaleBrandingEntity, computeCredentialLocaleBrandingState } from './CredentialLocaleBrandingEntity'
|
|
16
|
+
import { computeCompactHash } from '../../utils/issuanceBranding/HashUtils'
|
|
16
17
|
|
|
17
18
|
@Entity('CredentialBranding')
|
|
18
19
|
@Index('IDX_CredentialBrandingEntity_vcHash', ['vcHash'])
|
|
@@ -29,6 +30,9 @@ export class CredentialBrandingEntity extends BaseEntity {
|
|
|
29
30
|
@IsNotEmpty({ message: 'Blank issuerCorrelationIds are not allowed' })
|
|
30
31
|
issuerCorrelationId!: string
|
|
31
32
|
|
|
33
|
+
@Column('varchar', { name: 'state', length: 255, nullable: false })
|
|
34
|
+
state!: string
|
|
35
|
+
|
|
32
36
|
@OneToMany(
|
|
33
37
|
() => CredentialLocaleBrandingEntity,
|
|
34
38
|
(credentialLocaleBrandingEntity: CredentialLocaleBrandingEntity) => credentialLocaleBrandingEntity.credentialBranding,
|
|
@@ -55,6 +59,14 @@ export class CredentialBrandingEntity extends BaseEntity {
|
|
|
55
59
|
this.lastUpdatedAt = new Date()
|
|
56
60
|
}
|
|
57
61
|
|
|
62
|
+
@BeforeInsert()
|
|
63
|
+
@BeforeUpdate()
|
|
64
|
+
setState(): void {
|
|
65
|
+
if (this.localeBranding && Array.isArray(this.localeBranding)) {
|
|
66
|
+
this.state = this.computeState()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
58
70
|
@BeforeInsert()
|
|
59
71
|
@BeforeUpdate()
|
|
60
72
|
async validate(): Promise<undefined> {
|
|
@@ -64,4 +76,35 @@ export class CredentialBrandingEntity extends BaseEntity {
|
|
|
64
76
|
}
|
|
65
77
|
return
|
|
66
78
|
}
|
|
79
|
+
|
|
80
|
+
private computeState(): string {
|
|
81
|
+
const localeStates: Array<{ locale: string; alias: string; id: string; state: string }> = (this.localeBranding ?? []).map(
|
|
82
|
+
(localeBranding: CredentialLocaleBrandingEntity) => ({
|
|
83
|
+
locale: localeBranding.locale ?? '',
|
|
84
|
+
alias: localeBranding.alias ?? '',
|
|
85
|
+
id: localeBranding.id ?? '',
|
|
86
|
+
state: computeCredentialLocaleBrandingState(localeBranding),
|
|
87
|
+
}),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
localeStates.sort((first, second) => {
|
|
91
|
+
const localeCompare: number = first.locale.localeCompare(second.locale)
|
|
92
|
+
if (localeCompare !== 0) {
|
|
93
|
+
return localeCompare
|
|
94
|
+
}
|
|
95
|
+
const aliasCompare: number = first.alias.localeCompare(second.alias)
|
|
96
|
+
if (aliasCompare !== 0) {
|
|
97
|
+
return aliasCompare
|
|
98
|
+
}
|
|
99
|
+
return first.id.localeCompare(second.id)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
const payload = {
|
|
103
|
+
issuerCorrelationId: this.issuerCorrelationId,
|
|
104
|
+
vcHash: this.vcHash,
|
|
105
|
+
localeBranding: localeStates.map((entry) => entry.state),
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return computeCompactHash(JSON.stringify(payload))
|
|
109
|
+
}
|
|
67
110
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ChildEntity, Column, Index, JoinColumn, ManyToOne, OneToMany } from 'typeorm'
|
|
1
|
+
import { BeforeInsert, BeforeUpdate, ChildEntity, Column, Index, JoinColumn, ManyToOne, OneToMany } from 'typeorm'
|
|
2
|
+
import { computeCompactHash } from '../../utils/issuanceBranding/HashUtils'
|
|
2
3
|
import { BaseLocaleBrandingEntity } from './BaseLocaleBrandingEntity'
|
|
3
4
|
import { CredentialBrandingEntity } from './CredentialBrandingEntity'
|
|
4
5
|
import { CredentialClaimsEntity } from './CredentialClaimsEntity'
|
|
@@ -23,4 +24,66 @@ export class CredentialLocaleBrandingEntity extends BaseLocaleBrandingEntity {
|
|
|
23
24
|
|
|
24
25
|
@Column('uuid', { name: 'credentialBrandingId', nullable: false })
|
|
25
26
|
credentialBrandingId!: string
|
|
27
|
+
|
|
28
|
+
@Column('varchar', { name: 'state', length: 255, nullable: false })
|
|
29
|
+
state!: string
|
|
30
|
+
|
|
31
|
+
@BeforeInsert()
|
|
32
|
+
@BeforeUpdate()
|
|
33
|
+
setState(): void {
|
|
34
|
+
this.state = computeCredentialLocaleBrandingState(this)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const computeCredentialLocaleBrandingState = (localeBranding: CredentialLocaleBrandingEntity): string => {
|
|
39
|
+
const sortedClaims: Array<{ key: string; name: string }> = (localeBranding.claims ?? [])
|
|
40
|
+
.map((claim: CredentialClaimsEntity) => ({ key: claim.key, name: claim.name }))
|
|
41
|
+
.sort((first: { key: string }, second: { key: string }) => first.key.localeCompare(second.key))
|
|
42
|
+
|
|
43
|
+
const payload = {
|
|
44
|
+
alias: localeBranding.alias ?? null,
|
|
45
|
+
locale: localeBranding.locale ?? null,
|
|
46
|
+
description: localeBranding.description ?? null,
|
|
47
|
+
logo: localeBranding.logo
|
|
48
|
+
? {
|
|
49
|
+
uri: localeBranding.logo.uri ?? null,
|
|
50
|
+
dataUri: localeBranding.logo.dataUri ?? null,
|
|
51
|
+
mediaType: localeBranding.logo.mediaType ?? null,
|
|
52
|
+
alt: localeBranding.logo.alt ?? null,
|
|
53
|
+
dimensions: localeBranding.logo.dimensions
|
|
54
|
+
? {
|
|
55
|
+
width: localeBranding.logo.dimensions.width,
|
|
56
|
+
height: localeBranding.logo.dimensions.height,
|
|
57
|
+
}
|
|
58
|
+
: null,
|
|
59
|
+
}
|
|
60
|
+
: null,
|
|
61
|
+
background: localeBranding.background
|
|
62
|
+
? {
|
|
63
|
+
color: localeBranding.background.color ?? null,
|
|
64
|
+
image: localeBranding.background.image
|
|
65
|
+
? {
|
|
66
|
+
uri: localeBranding.background.image.uri ?? null,
|
|
67
|
+
dataUri: localeBranding.background.image.dataUri ?? null,
|
|
68
|
+
mediaType: localeBranding.background.image.mediaType ?? null,
|
|
69
|
+
alt: localeBranding.background.image.alt ?? null,
|
|
70
|
+
dimensions: localeBranding.background.image.dimensions
|
|
71
|
+
? {
|
|
72
|
+
width: localeBranding.background.image.dimensions.width,
|
|
73
|
+
height: localeBranding.background.image.dimensions.height,
|
|
74
|
+
}
|
|
75
|
+
: null,
|
|
76
|
+
}
|
|
77
|
+
: null,
|
|
78
|
+
}
|
|
79
|
+
: null,
|
|
80
|
+
text: localeBranding.text
|
|
81
|
+
? {
|
|
82
|
+
color: localeBranding.text.color ?? null,
|
|
83
|
+
}
|
|
84
|
+
: null,
|
|
85
|
+
claims: sortedClaims,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return computeCompactHash(JSON.stringify(payload))
|
|
26
89
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Validate } from 'class-validator'
|
|
2
|
-
import { ChildEntity, Column, Index, JoinColumn, ManyToOne } from 'typeorm'
|
|
2
|
+
import { BeforeInsert, BeforeUpdate, ChildEntity, Column, Index, JoinColumn, ManyToOne } from 'typeorm'
|
|
3
|
+
import { computeCompactHash } from '../../utils/issuanceBranding/HashUtils'
|
|
3
4
|
import { IsNonEmptyStringConstraint } from '../validators'
|
|
4
5
|
import { BaseLocaleBrandingEntity } from './BaseLocaleBrandingEntity'
|
|
5
6
|
import { IssuerBrandingEntity } from './IssuerBrandingEntity'
|
|
@@ -30,4 +31,65 @@ export class IssuerLocaleBrandingEntity extends BaseLocaleBrandingEntity {
|
|
|
30
31
|
|
|
31
32
|
@Column('text', { name: 'issuerBrandingId', nullable: false })
|
|
32
33
|
issuerBrandingId!: string
|
|
34
|
+
|
|
35
|
+
@Column('varchar', { name: 'state', length: 255, nullable: false })
|
|
36
|
+
state!: string
|
|
37
|
+
|
|
38
|
+
@BeforeInsert()
|
|
39
|
+
@BeforeUpdate()
|
|
40
|
+
setState(): void {
|
|
41
|
+
this.state = this.computeState()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private computeState(): string {
|
|
45
|
+
const payload = {
|
|
46
|
+
alias: this.alias ?? null,
|
|
47
|
+
locale: this.locale ?? null,
|
|
48
|
+
description: this.description ?? null,
|
|
49
|
+
clientUri: this.clientUri ?? null,
|
|
50
|
+
tosUri: this.tosUri ?? null,
|
|
51
|
+
policyUri: this.policyUri ?? null,
|
|
52
|
+
contacts: this.contacts ?? null,
|
|
53
|
+
logo: this.logo
|
|
54
|
+
? {
|
|
55
|
+
uri: this.logo.uri ?? null,
|
|
56
|
+
dataUri: this.logo.dataUri ?? null,
|
|
57
|
+
mediaType: this.logo.mediaType ?? null,
|
|
58
|
+
alt: this.logo.alt ?? null,
|
|
59
|
+
dimensions: this.logo.dimensions
|
|
60
|
+
? {
|
|
61
|
+
width: this.logo.dimensions.width,
|
|
62
|
+
height: this.logo.dimensions.height,
|
|
63
|
+
}
|
|
64
|
+
: null,
|
|
65
|
+
}
|
|
66
|
+
: null,
|
|
67
|
+
background: this.background
|
|
68
|
+
? {
|
|
69
|
+
color: this.background.color ?? null,
|
|
70
|
+
image: this.background.image
|
|
71
|
+
? {
|
|
72
|
+
uri: this.background.image.uri ?? null,
|
|
73
|
+
dataUri: this.background.image.dataUri ?? null,
|
|
74
|
+
mediaType: this.background.image.mediaType ?? null,
|
|
75
|
+
alt: this.background.image.alt ?? null,
|
|
76
|
+
dimensions: this.background.image.dimensions
|
|
77
|
+
? {
|
|
78
|
+
width: this.background.image.dimensions.width,
|
|
79
|
+
height: this.background.image.dimensions.height,
|
|
80
|
+
}
|
|
81
|
+
: null,
|
|
82
|
+
}
|
|
83
|
+
: null,
|
|
84
|
+
}
|
|
85
|
+
: null,
|
|
86
|
+
text: this.text
|
|
87
|
+
? {
|
|
88
|
+
color: this.text.color ?? null,
|
|
89
|
+
}
|
|
90
|
+
: null,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return computeCompactHash(JSON.stringify(payload))
|
|
94
|
+
}
|
|
33
95
|
}
|