serverNotificationHandler method
Handler for revoking sessions based on server-to-server notifications coming from Apple.
To be mounted as a POST handler under the URL configured in Apple's
developer portal, for example:
Router<Handler>()..post(
'/hooks/apple-notification',
handleAppleNotification, // your function to handle the notification
);
If the notification is of type AppleServerNotificationConsentRevoked or
AppleServerNotificationAccountDelete, all sessions based on the Apple
authentication for that account will be revoked.
Implementation
Future<Result> serverNotificationHandler(
final Session session,
final Request req,
) async {
final body = await utf8.decodeStream(req.body.read());
final payload = (jsonDecode(body) as Map)['payload'] as String;
final notification = await _signInWithApple.decodeAppleServerNotification(
payload,
);
final userIdentifier = switch (notification) {
AppleServerNotificationConsentRevoked() => notification.userIdentifier,
AppleServerNotificationAccountDelete() => notification.userIdentifier,
_ => null,
};
if (userIdentifier != null) {
final appleAccount = await AppleAccount.db.findFirstRow(
session,
where: (final t) => t.userIdentifier.equals(userIdentifier),
);
if (appleAccount != null) {
await _signInWithApple.revokeAuthorization(
refreshToken: appleAccount.refreshToken,
useBundleIdentifier:
appleAccount.refreshTokenRequestedWithBundleIdentifier,
);
await _tokenManager.revokeAllTokens(
session,
authUserId: appleAccount.authUserId,
method: AppleIdp.method,
);
if (notification is AppleServerNotificationAccountDelete) {
await AppleAccount.db.deleteRow(session, appleAccount);
}
}
}
return Response.ok();
}