$assistantIds active public assistants that would be affected */ public static function issue(string $secret, int $siteId, int $sourceId, int $userId, int $sourceUpdatedAt, array $assistantIds, int $now): string { return self::sign($secret, $siteId, $sourceId, $userId, $sourceUpdatedAt, $assistantIds, $now + self::TTL); } /** @param list $assistantIds the CURRENT set, read inside the publishing transaction */ public static function valid(string $token, string $secret, int $siteId, int $sourceId, int $userId, int $sourceUpdatedAt, array $assistantIds, int $now): bool { if (!preg_match('/^(\d{9,12})\.([0-9a-f]{64})$/D', $token, $m)) { return false; } $expires = (int) $m[1]; if ($expires < $now || $expires > $now + self::TTL) { return false; } return hash_equals(self::sign($secret, $siteId, $sourceId, $userId, $sourceUpdatedAt, $assistantIds, $expires), $token); } /** @param list $assistantIds */ private static function sign(string $secret, int $siteId, int $sourceId, int $userId, int $updatedAt, array $assistantIds, int $expires): string { sort($assistantIds); $mac = hash_hmac('sha256', implode('|', ['aiwend-publish-v1', $siteId, $sourceId, $userId, $updatedAt, implode(',', $assistantIds), $expires]), $secret); return $expires . '.' . $mac; } }