@rmdes/indiekit-endpoint-activitypub 3.5.3 → 3.5.4
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/lib/mastodon/routes/oauth.js +48 -5
- package/package.json +1 -1
|
@@ -158,7 +158,7 @@ router.get("/.well-known/oauth-authorization-server", (req, res) => {
|
|
|
158
158
|
"write:statuses",
|
|
159
159
|
],
|
|
160
160
|
response_types_supported: ["code"],
|
|
161
|
-
grant_types_supported: ["authorization_code", "client_credentials"],
|
|
161
|
+
grant_types_supported: ["authorization_code", "client_credentials", "refresh_token"],
|
|
162
162
|
token_endpoint_auth_methods_supported: [
|
|
163
163
|
"client_secret_basic",
|
|
164
164
|
"client_secret_post",
|
|
@@ -423,10 +423,49 @@ router.post("/oauth/token", async (req, res, next) => {
|
|
|
423
423
|
});
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
// ─── Refresh token grant ──────────────────────────────────────────
|
|
427
|
+
if (grant_type === "refresh_token") {
|
|
428
|
+
const { refresh_token } = req.body;
|
|
429
|
+
if (!refresh_token) {
|
|
430
|
+
return res.status(400).json({
|
|
431
|
+
error: "invalid_request",
|
|
432
|
+
error_description: "Missing refresh_token",
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const existing = await collections.ap_oauth_tokens.findOne({
|
|
437
|
+
refreshToken: refresh_token,
|
|
438
|
+
revokedAt: null,
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
if (!existing) {
|
|
442
|
+
return res.status(400).json({
|
|
443
|
+
error: "invalid_grant",
|
|
444
|
+
error_description: "Refresh token is invalid or revoked",
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Rotate: new access token + new refresh token
|
|
449
|
+
const newAccessToken = randomHex(64);
|
|
450
|
+
const newRefreshToken = randomHex(64);
|
|
451
|
+
await collections.ap_oauth_tokens.updateOne(
|
|
452
|
+
{ _id: existing._id },
|
|
453
|
+
{ $set: { accessToken: newAccessToken, refreshToken: newRefreshToken } },
|
|
454
|
+
);
|
|
455
|
+
|
|
456
|
+
return res.json({
|
|
457
|
+
access_token: newAccessToken,
|
|
458
|
+
token_type: "Bearer",
|
|
459
|
+
scope: existing.scopes.join(" "),
|
|
460
|
+
created_at: Math.floor(existing.createdAt.getTime() / 1000),
|
|
461
|
+
refresh_token: newRefreshToken,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
426
465
|
if (grant_type !== "authorization_code") {
|
|
427
466
|
return res.status(400).json({
|
|
428
467
|
error: "unsupported_grant_type",
|
|
429
|
-
error_description: "Only authorization_code and
|
|
468
|
+
error_description: "Only authorization_code, client_credentials, and refresh_token are supported",
|
|
430
469
|
});
|
|
431
470
|
}
|
|
432
471
|
|
|
@@ -487,11 +526,13 @@ router.post("/oauth/token", async (req, res, next) => {
|
|
|
487
526
|
}
|
|
488
527
|
}
|
|
489
528
|
|
|
490
|
-
// Generate access token
|
|
529
|
+
// Generate access token and refresh token.
|
|
530
|
+
// Clear expiresAt — it was set for the auth code, not the access token.
|
|
491
531
|
const accessToken = randomHex(64);
|
|
532
|
+
const refreshToken = randomHex(64);
|
|
492
533
|
await collections.ap_oauth_tokens.updateOne(
|
|
493
534
|
{ _id: grant._id },
|
|
494
|
-
{ $set: { accessToken } },
|
|
535
|
+
{ $set: { accessToken, refreshToken, expiresAt: null } },
|
|
495
536
|
);
|
|
496
537
|
|
|
497
538
|
res.json({
|
|
@@ -499,6 +540,7 @@ router.post("/oauth/token", async (req, res, next) => {
|
|
|
499
540
|
token_type: "Bearer",
|
|
500
541
|
scope: grant.scopes.join(" "),
|
|
501
542
|
created_at: Math.floor(grant.createdAt.getTime() / 1000),
|
|
543
|
+
refresh_token: refreshToken,
|
|
502
544
|
});
|
|
503
545
|
} catch (error) {
|
|
504
546
|
next(error);
|
|
@@ -519,8 +561,9 @@ router.post("/oauth/revoke", async (req, res, next) => {
|
|
|
519
561
|
}
|
|
520
562
|
|
|
521
563
|
const collections = req.app.locals.mastodonCollections;
|
|
564
|
+
// Match by access token or refresh token
|
|
522
565
|
await collections.ap_oauth_tokens.updateOne(
|
|
523
|
-
{ accessToken: token },
|
|
566
|
+
{ $or: [{ accessToken: token }, { refreshToken: token }] },
|
|
524
567
|
{ $set: { revokedAt: new Date() } },
|
|
525
568
|
);
|
|
526
569
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rmdes/indiekit-endpoint-activitypub",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.4",
|
|
4
4
|
"description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"indiekit",
|