+25
-1
src/Data/AccessToken.php
+25
-1
src/Data/AccessToken.php
···
2
2
3
3
namespace SocialDept\AtpClient\Data;
4
4
5
+
use Carbon\Carbon;
5
6
use SocialDept\AtpClient\Enums\AuthType;
6
7
7
8
class AccessToken
···
40
41
}
41
42
42
43
// Legacy createSession format (app passwords have full access)
44
+
// Parse expiry from JWT since createSession doesn't return expiresIn
45
+
$expiresAt = self::parseJwtExpiry($data['accessJwt']) ?? now()->addHour();
46
+
43
47
return new self(
44
48
accessJwt: $data['accessJwt'],
45
49
refreshJwt: $data['refreshJwt'],
46
50
did: $data['did'],
47
-
expiresAt: now()->addSeconds($data['expiresIn'] ?? 300),
51
+
expiresAt: $expiresAt,
48
52
handle: $data['handle'] ?? $handle,
49
53
issuer: $issuer,
50
54
scope: ['atproto', 'transition:generic', 'transition:email'],
51
55
authType: AuthType::Legacy,
52
56
);
57
+
}
58
+
59
+
/**
60
+
* Parse the expiry timestamp from a JWT's payload.
61
+
*/
62
+
protected static function parseJwtExpiry(string $jwt): ?\DateTimeInterface
63
+
{
64
+
$parts = explode('.', $jwt);
65
+
66
+
if (count($parts) !== 3) {
67
+
return null;
68
+
}
69
+
70
+
$payload = json_decode(base64_decode(strtr($parts[1], '-_', '+/')), true);
71
+
72
+
if (! isset($payload['exp'])) {
73
+
return null;
74
+
}
75
+
76
+
return Carbon::createFromTimestamp($payload['exp']);
53
77
}
54
78
}