Changelog

What changed in each version of @unet/id-web: new calls, fixes, security fixes and breaking changes. Newest first.

Unreleased

  • Security: link previews. splitLinkPreview() returns url / image only when they are absolute http(s) addresses (the parsed address, what a browser will open). The preview line is written by whoever wrote the post, so javascript: / data: addresses used to reach <a href={preview.url}> in apps; now a preview without a safe address is none (the text still shows) and an unsafe picture is dropped.
  • Security: discovery. The discovery document must name the issuer that was asked and keep its authorization, token, userinfo and revocation endpoints on that issuer's origin over https; a cached copy is checked like a fresh one (a poisoned storage entry is ignored and replaced). The callback iss is compared with the configured issuer, and the issuer itself must be https (http only on localhost). Needs a server whose discovery issuer is its public address.
  • Security: ids in request paths. An id that is not a plain id (letters, digits, -, _) — or a path with a . / .. segment — makes the call fail with ApiError invalid_id before any request is sent; api.media() accepts only plain file-name segments. A plain-JS caller can no longer make the SDK call another endpoint with the person's token through an id like "1/../../me/settings".
  • Fix: the message of invalid_client names the current Developers Console wording.
  • Security fix (breaking): verifyAccessToken(token) only asked UNET whom a token belongs to, which answers for the token of any app, so another app could replay a token of the same person to your server and be let in as them. It now needs { clientId, clientSecret } (a website app) and uses token introspection: only a live token issued to your app is accepted, and it throws rather than answer "valid" when it cannot be sure. It returns scopes and expiresAt too; profile: false skips the profile request.
  • New: verifyIdToken(idToken, { clientId }) for single-page sites and apps without a secret — checks the ID token locally (RS256 signature against UNET's cached signing keys, issuer, audience, expiry), and unet.getIdToken() hands the front end the token to send to its own server.
  • New: more of the viewer's relationship on people — Profile.viewer.followedBy / blocked / muted, Profile.connectionsVisible, SearchUser.followers / viewer, Notification.actor.isPrivate / viewer, and PersonRef.viewer (follow state) on follower, following, mutual and likes / reposts lists. All absent on older servers.
  • New: Fediverse profiles like UNET ones — api.lookupFediverseActor("name@host") (open a profile from a plain handle), api.fediverseActorPosts(id, { replies }) (their posts and their replies apart), api.fediverseActorConnections(id, "followers" | "following"), and FediverseItem.inReplyTo.
  • New: api.commentLikes() / api.commentReposts() — who liked / reposted your comment ("View activity" of a comment; the post twins are postLikes() / postReposts()).
  • New: api.realtime() — live hints (new notifications, changes on posts you show, new posts in a feed) over server-sent events: Realtime with on / update / close, automatic reconnect, parseEvents.
  • New: comment pictures — api.uploadCommentImage(), api.comment({ images }) (files, uploaded for you) or { imageKeys }, and Comment.images.
  • New: api.postSubscription() / subscribeToPost() / unsubscribeFromPost() — watch one post for new comment activity (the bell on the post page).
  • New: Comment.likedByAuthor on comment lists (the author of the post liked the comment).
  • New: api.postLikes() / api.postReposts() (the author's view of who reacted), api.translatePost(), api.uploadAvatar() / uploadBanner() / removeBanner(), Post.allowTranslation, api.placePosts(), Post.isPinned, Post.hashId (and api.post() accepts it), Post.video.posterUrl.
  • Fix: a failed refresh signs the person out only when the server says the grant is gone (invalid_grant); invalid_request, 5xx and network errors keep the tokens and the next call tries again.
  • New: api.fediverse() / setFediverse() / fediverseFeed() (the Fediverse: status and switch, and the feed of accounts you follow there).
  • New: the rest of the Fediverse — searchFediverse(), fediverseActor() / fediverseActorPosts(), followOnFediverse() / unfollowOnFediverse(), blockOnFediverse() / unblockOnFediverse() / fediverseBlocked(), fediversePost() / fediverseThread(), likeOnFediverse() / boostOnFediverse() (and their undo), replyOnFediverse() / updateFediverseReply() / deleteFediverseReply(), voteInFediversePoll(), fediverseHashtag().
  • Change: api.pinPost() fails with 409 pin_limit_reached at three pinned posts.
  • New: api.mediaLink() — a short-lived link a <video src> streams from (byte ranges, no full download).
  • New: api.hashtagPosts() and api.topicPosts() (posts of a hashtag or a topic).
  • New: api.subscribeToAuthor() / unsubscribeFromAuthor() (the profile bell, Profile.viewer.subscribed), api.pinPost() / unpinPost(), api.notInterested() / notInterestedItems() / removeNotInterested(), api.mutualConnections(), Profile.links, Profile.mutual, FeedSettings.excludedTopicIds / excludedTopics.
  • New: api.settings() / updateSettings() (privacy, notifications, translation and link previews, “For you” feed), addMutedKeyword() / removeMutedKeyword(); scopes settings:read and settings:write (request them in scope to use these).

0.2.0

  • Fix: a 403 is InsufficientScope only when the server says insufficient_scope; otherwise ApiError (forbidden).
  • Fix: a 2xx response that is not JSON throws ApiError (invalid_response) instead of returning {}.
  • Fix: refresh is serialised across tabs (Web Locks) and picks up tokens another tab already refreshed; storage: "local" tabs mirror sign-in/out.
  • Fix: callback iss is checked (RFC 9207) when the server sends it.
  • New: getGrantedScopes(), hasScope(), refreshUser(), restore({ revalidate: false }), cached discovery and profile.
  • New: signIn({ prompt, loginHint, extraParams }).
  • New: timeoutMs, retries / maxRetryDelayMs, api.withSignal(signal), paginate().
  • New: verifyAccessToken() for backends.
  • New: Profile.viewer (following, pending) when the server provides it.
  • Build: source maps and declaration maps, engines, CHANGELOG.

0.1.0

  • Initial release.