cortex-auth 1.6.0 → 1.7.0
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/crypto.d.ts +17 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +72 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/payload-jwt/configuration.d.ts.map +1 -1
- package/dist/payload-jwt/configuration.js +11 -5
- package/dist/payload-jwt/configuration.js.map +1 -1
- package/dist/payload-jwt/getAccessToken.d.ts.map +1 -1
- package/dist/payload-jwt/getAccessToken.js +20 -7
- package/dist/payload-jwt/getAccessToken.js.map +1 -1
- package/package.json +1 -1
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encrypts a token using AES-256-GCM encryption
|
|
3
|
+
* @param token - The token string to encrypt
|
|
4
|
+
* @param secret - The encryption key (PAYLOAD_SECRET)
|
|
5
|
+
* @param userId - The user ID to include in key derivation
|
|
6
|
+
* @returns The encrypted token in format: iv:authTag:encryptedData (hex encoded)
|
|
7
|
+
*/
|
|
8
|
+
export declare function encryptToken(token: string | null | undefined, secret: string, userId: string): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Decrypts a token that was encrypted with encryptToken
|
|
11
|
+
* @param encryptedToken - The encrypted token string in format: iv:authTag:encryptedData
|
|
12
|
+
* @param secret - The encryption key (PAYLOAD_SECRET)
|
|
13
|
+
* @param userId - The user ID to include in key derivation
|
|
14
|
+
* @returns The decrypted token string
|
|
15
|
+
*/
|
|
16
|
+
export declare function decryptToken(encryptedToken: string | null | undefined, secret: string, userId: string): string | null;
|
|
17
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2B5G;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoCrH"}
|
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createHash, createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Encrypts a token using AES-256-GCM encryption
|
|
4
|
+
* @param token - The token string to encrypt
|
|
5
|
+
* @param secret - The encryption key (PAYLOAD_SECRET)
|
|
6
|
+
* @param userId - The user ID to include in key derivation
|
|
7
|
+
* @returns The encrypted token in format: iv:authTag:encryptedData (hex encoded)
|
|
8
|
+
*/
|
|
9
|
+
export function encryptToken(token, secret, userId) {
|
|
10
|
+
if (!token)
|
|
11
|
+
return null;
|
|
12
|
+
try {
|
|
13
|
+
// Generate a 32-byte key from the secret and userId using SHA-256
|
|
14
|
+
// Combine PAYLOAD_SECRET with userId for per-user encryption keys
|
|
15
|
+
const key = createHash('sha256').update(secret).update(userId).digest();
|
|
16
|
+
// Generate a random 12-byte initialization vector
|
|
17
|
+
const iv = randomBytes(12);
|
|
18
|
+
// Create cipher
|
|
19
|
+
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
|
20
|
+
// Encrypt the token
|
|
21
|
+
let encrypted = cipher.update(token, 'utf8', 'hex');
|
|
22
|
+
encrypted += cipher.final('hex');
|
|
23
|
+
// Get the auth tag for GCM mode
|
|
24
|
+
const authTag = cipher.getAuthTag();
|
|
25
|
+
// Return format: iv:authTag:encryptedData
|
|
26
|
+
return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.error('Error encrypting token');
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Decrypts a token that was encrypted with encryptToken
|
|
35
|
+
* @param encryptedToken - The encrypted token string in format: iv:authTag:encryptedData
|
|
36
|
+
* @param secret - The encryption key (PAYLOAD_SECRET)
|
|
37
|
+
* @param userId - The user ID to include in key derivation
|
|
38
|
+
* @returns The decrypted token string
|
|
39
|
+
*/
|
|
40
|
+
export function decryptToken(encryptedToken, secret, userId) {
|
|
41
|
+
if (!encryptedToken)
|
|
42
|
+
return null;
|
|
43
|
+
try {
|
|
44
|
+
// Parse the encrypted token format
|
|
45
|
+
const parts = encryptedToken.split(':');
|
|
46
|
+
if (parts.length !== 3) {
|
|
47
|
+
// Token might be unencrypted (backward compatibility during migration)
|
|
48
|
+
// Log for audit purposes
|
|
49
|
+
console.warn('Encountered potentially unencrypted token in database - migration may be needed');
|
|
50
|
+
return encryptedToken;
|
|
51
|
+
}
|
|
52
|
+
const [ivHex, authTagHex, encryptedData] = parts;
|
|
53
|
+
// Generate the same key from the secret and userId
|
|
54
|
+
// Must match the key generation in encryptToken
|
|
55
|
+
const key = createHash('sha256').update(secret).update(userId).digest();
|
|
56
|
+
// Convert hex strings back to buffers
|
|
57
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
58
|
+
const authTag = Buffer.from(authTagHex, 'hex');
|
|
59
|
+
// Create decipher
|
|
60
|
+
const decipher = createDecipheriv('aes-256-gcm', key, iv);
|
|
61
|
+
decipher.setAuthTag(authTag);
|
|
62
|
+
// Decrypt the token
|
|
63
|
+
let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
|
|
64
|
+
decrypted += decipher.final('utf8');
|
|
65
|
+
return decrypted;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error('Error decrypting token');
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAExF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAgC,EAAE,MAAc,EAAE,MAAc;IAC3F,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,IAAI,CAAC;QACH,kEAAkE;QAClE,kEAAkE;QAClE,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAExE,kDAAkD;QAClD,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;QAE3B,gBAAgB;QAChB,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QAEtD,oBAAoB;QACpB,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACpD,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAEjC,gCAAgC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAEpC,0CAA0C;QAC1C,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,cAAyC,EAAE,MAAc,EAAE,MAAc;IACpG,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEjC,IAAI,CAAC;QACH,mCAAmC;QACnC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,uEAAuE;YACvE,yBAAyB;YACzB,OAAO,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAC;YAChG,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC;QAEjD,mDAAmD;QACnD,gDAAgD;QAChD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAExE,sCAAsC;QACtC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE/C,kBAAkB;QAClB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QAC1D,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAE7B,oBAAoB;QACpB,IAAI,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC9D,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEpC,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/payload-jwt/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/payload-jwt/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAQ9C,KAAK,eAAe,GAAG;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,iBAAiB,EAAE,MAAM,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,CAAA;AAuCD,iBAAS,YAAY,CAAC,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,MAAM,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE;SAAzF,MAAM;;;EAQ3C;AAGD,iBAAe,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,CAAC,eAAe,CAAC,iBAuB7G;AAoED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAM7B,CAAC"}
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { decodeJwt } from 'jose';
|
|
2
2
|
import { getPayload } from 'payload';
|
|
3
3
|
import { payloadAcl } from '../payload-access/access.js';
|
|
4
|
-
|
|
4
|
+
import { encryptToken } from '../crypto';
|
|
5
|
+
function upsertAccount(existing = [], account, userId) {
|
|
5
6
|
const provider = account.provider;
|
|
6
7
|
const providerAccountId = account.providerAccountId;
|
|
7
8
|
const idx = existing.findIndex((a) => a.provider === provider && a.providerAccountId === providerAccountId);
|
|
9
|
+
// Get the PAYLOAD_SECRET for encryption
|
|
10
|
+
const secret = process.env.PAYLOAD_SECRET;
|
|
11
|
+
if (!secret) {
|
|
12
|
+
throw new Error('PAYLOAD_SECRET environment variable is required for token encryption');
|
|
13
|
+
}
|
|
8
14
|
const nextRow = {
|
|
9
15
|
provider,
|
|
10
16
|
providerAccountId,
|
|
11
17
|
type: account.type, // Cast to match AccountType
|
|
12
|
-
//
|
|
13
|
-
access_token: account.access_token
|
|
14
|
-
refresh_token: account.refresh_token
|
|
18
|
+
// Encrypt tokens before storing (must match your Users.accounts[] schema)
|
|
19
|
+
access_token: encryptToken(account.access_token, secret, userId),
|
|
20
|
+
refresh_token: encryptToken(account.refresh_token, secret, userId),
|
|
15
21
|
expires_at: account.expires_at ?? null,
|
|
16
22
|
id_token: account.id_token ?? null,
|
|
17
23
|
token_type: account.token_type ?? null,
|
|
@@ -43,7 +49,7 @@ async function persistTokens(userId, account, payloadConfig) {
|
|
|
43
49
|
depth: 0,
|
|
44
50
|
});
|
|
45
51
|
const existing = fullUser.accounts ?? [];
|
|
46
|
-
const accounts = upsertAccount(existing, account);
|
|
52
|
+
const accounts = upsertAccount(existing, account, userId);
|
|
47
53
|
let role = 'user'; // default role
|
|
48
54
|
if (account && account.access_token) {
|
|
49
55
|
const decodedJWT = decodeJwt(account.access_token);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../src/payload-jwt/configuration.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../src/payload-jwt/configuration.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAccessToken.d.ts","sourceRoot":"","sources":["../../src/payload-jwt/getAccessToken.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"getAccessToken.d.ts","sourceRoot":"","sources":["../../src/payload-jwt/getAccessToken.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAKtC,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,0BAgEpE"}
|
|
@@ -1,14 +1,26 @@
|
|
|
1
|
+
import { decryptToken, encryptToken } from '../crypto';
|
|
1
2
|
export async function getAccessToken(payload, userId) {
|
|
2
3
|
const user = await payload.findByID({ collection: "users", id: userId, depth: 0 });
|
|
3
4
|
const kc = user?.accounts?.find((a) => a.provider === "keycloak");
|
|
4
|
-
if
|
|
5
|
+
// Check if keycloak account exists
|
|
6
|
+
if (!kc)
|
|
7
|
+
return null;
|
|
8
|
+
// Get the PAYLOAD_SECRET for decryption
|
|
9
|
+
const secret = process.env.PAYLOAD_SECRET;
|
|
10
|
+
if (!secret) {
|
|
11
|
+
throw new Error('PAYLOAD_SECRET environment variable is required for token decryption');
|
|
12
|
+
}
|
|
13
|
+
// Decrypt the access token
|
|
14
|
+
const decryptedAccessToken = decryptToken(kc.access_token, secret, userId);
|
|
15
|
+
if (!decryptedAccessToken)
|
|
5
16
|
return null;
|
|
6
17
|
const expiresAt = kc.expires_at ?? 0;
|
|
7
18
|
const stillValid = expiresAt === 0 || Date.now() < expiresAt * 1000 - 30000; // 30s skew
|
|
8
19
|
if (stillValid)
|
|
9
|
-
return
|
|
20
|
+
return decryptedAccessToken;
|
|
10
21
|
// Refresh if needed
|
|
11
|
-
|
|
22
|
+
const decryptedRefreshToken = decryptToken(kc.refresh_token, secret, userId);
|
|
23
|
+
if (!decryptedRefreshToken)
|
|
12
24
|
return null;
|
|
13
25
|
const resp = await fetch(`${process.env.OAUTH_ISSUER}/protocol/openid-connect/token`, {
|
|
14
26
|
method: "POST",
|
|
@@ -17,20 +29,21 @@ export async function getAccessToken(payload, userId) {
|
|
|
17
29
|
client_id: process.env.OAUTH_CLIENT_ID,
|
|
18
30
|
client_secret: process.env.OAUTH_CLIENT_SECRET,
|
|
19
31
|
grant_type: "refresh_token",
|
|
20
|
-
refresh_token:
|
|
32
|
+
refresh_token: decryptedRefreshToken,
|
|
21
33
|
}),
|
|
22
34
|
});
|
|
23
35
|
if (!resp.ok)
|
|
24
36
|
return null;
|
|
25
37
|
const json = await resp.json();
|
|
26
38
|
const newExpiresAt = Math.floor(Date.now() / 1000 + json.expires_in);
|
|
27
|
-
//
|
|
39
|
+
// Encrypt new tokens before persisting back into users.accounts[]
|
|
28
40
|
const accounts = (user.accounts ?? []).map((a) => a?.provider === "keycloak"
|
|
29
41
|
? {
|
|
30
42
|
...a,
|
|
31
|
-
access_token: json.access_token,
|
|
43
|
+
access_token: encryptToken(json.access_token, secret, userId),
|
|
32
44
|
expires_at: newExpiresAt,
|
|
33
|
-
|
|
45
|
+
// Use new refresh token if provided, otherwise keep the existing encrypted one
|
|
46
|
+
refresh_token: json.refresh_token ? encryptToken(json.refresh_token, secret, userId) : a.refresh_token,
|
|
34
47
|
}
|
|
35
48
|
: a);
|
|
36
49
|
await payload.update({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAccessToken.js","sourceRoot":"","sources":["../../src/payload-jwt/getAccessToken.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getAccessToken.js","sourceRoot":"","sources":["../../src/payload-jwt/getAccessToken.ts"],"names":[],"mappings":"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"}
|