Skip to content

Commit 13012d9

Browse files
committed
refactor: enhance JWT generation methods and update .env.example comments for clarity
1 parent a58be2a commit 13012d9

File tree

3 files changed

+26
-42
lines changed

3 files changed

+26
-42
lines changed

example/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ITBL_API_KEY=replace_this_with_your_iterable_api_key
2020
# Your JWT Secret, created when making your API key (see above)
2121
ITBL_JWT_SECRET=replace_this_with_your_jwt_secret
2222
# Is your api token JWT Enabled?
23-
# Defaults to true
23+
# Must be set to 'true' to enable JWT authentication
2424
ITBL_IS_JWT_ENABLED=true
2525

2626
# Your Iterable user ID or email address

example/ios/IterableJwtGenerator.swift

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ import Foundation
1010

1111
@objcMembers public final class IterableJwtGenerator: NSObject {
1212

13+
private struct Header: Encodable {
14+
let alg = "HS256"
15+
let typ = "JWT"
16+
}
17+
1318
/// Base64 URL encode without padding (URL-safe base64 encoding for JWT)
1419
private static func urlEncodedBase64(_ data: Data) -> String {
1520
let base64 = data.base64EncodedString()
@@ -20,24 +25,12 @@ import Foundation
2025
.replacingOccurrences(of: "=", with: "")
2126
}
2227

23-
public static func generateJwtForEmail(secret: String, iat: Int, exp: Int, email: String)
24-
-> String
25-
{
26-
struct Header: Encodable {
27-
let alg = "HS256"
28-
let typ = "JWT"
29-
}
30-
31-
struct Payload: Encodable {
32-
var email = ""
33-
var iat = Int(Date().timeIntervalSince1970)
34-
var exp = Int(Date().timeIntervalSince1970) + 60
35-
36-
}
28+
/// Generic JWT generation helper that works with any Encodable payload
29+
private static func generateJwt<T: Encodable>(secret: String, payload: T) -> String {
3730
let headerJsonData = try! JSONEncoder().encode(Header())
3831
let headerBase64 = urlEncodedBase64(headerJsonData)
3932

40-
let payloadJsonData = try! JSONEncoder().encode(Payload(email: email, iat: iat, exp: exp))
33+
let payloadJsonData = try! JSONEncoder().encode(payload)
4134
let payloadBase64 = urlEncodedBase64(payloadJsonData)
4235

4336
let toSign = Data((headerBase64 + "." + payloadBase64).utf8)
@@ -54,38 +47,28 @@ import Foundation
5447
return ""
5548
}
5649

57-
public static func generateJwtForUserId(secret: String, iat: Int, exp: Int, userId: String)
50+
public static func generateJwtForEmail(secret: String, iat: Int, exp: Int, email: String)
5851
-> String
5952
{
60-
struct Header: Encodable {
61-
let alg = "HS256"
62-
let typ = "JWT"
63-
}
64-
6553
struct Payload: Encodable {
66-
var userId = ""
67-
var iat = Int(Date().timeIntervalSince1970)
68-
var exp = Int(Date().timeIntervalSince1970) + 60
69-
54+
var email: String
55+
var iat: Int
56+
var exp: Int
7057
}
71-
let headerJsonData = try! JSONEncoder().encode(Header())
72-
let headerBase64 = urlEncodedBase64(headerJsonData)
7358

74-
let payloadJsonData = try! JSONEncoder().encode(Payload(userId: userId, iat: iat, exp: exp))
75-
let payloadBase64 = urlEncodedBase64(payloadJsonData)
76-
77-
let toSign = Data((headerBase64 + "." + payloadBase64).utf8)
78-
79-
if #available(iOS 13.0, *) {
80-
let privateKey = SymmetricKey(data: Data(secret.utf8))
81-
let signature = HMAC<SHA256>.authenticationCode(for: toSign, using: privateKey)
82-
let signatureBase64 = urlEncodedBase64(Data(signature))
83-
84-
let token = [headerBase64, payloadBase64, signatureBase64].joined(separator: ".")
59+
return generateJwt(secret: secret, payload: Payload(email: email, iat: iat, exp: exp))
60+
}
8561

86-
return token
62+
public static func generateJwtForUserId(secret: String, iat: Int, exp: Int, userId: String)
63+
-> String
64+
{
65+
struct Payload: Encodable {
66+
var userId: String
67+
var iat: Int
68+
var exp: Int
8769
}
88-
return ""
70+
71+
return generateJwt(secret: secret, payload: Payload(userId: userId, iat: iat, exp: exp))
8972
}
9073

9174
public static func generateToken(

example/src/hooks/useIterableApp.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ export const IterableAppProvider: FunctionComponent<
235235
return Promise.reject(err);
236236
});
237237
},
238-
[getUserId, apiKey, login, getJwtToken]
238+
// eslint-disable-next-line react-hooks/exhaustive-deps
239+
[getUserId, apiKey, login, getJwtToken, userId]
239240
);
240241

241242
const logout = useCallback(() => {

0 commit comments

Comments
 (0)