Repository navigation
Serve notifications for the validated account only #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
hiveuprss
wants to merge
1
commit into
ecency:main
from
hiveuprss:cursor/notifications-validate-code-only-8fd6
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,15 +13,17 @@ public static partial class PrivateApi | |
| /// <summary> | ||
| /// Who a notifications request is for, and whether it may see the complete feed. | ||
| /// | ||
| /// A null Username means unauthorized. `requestedUser` is the body's `user` field | ||
| /// after JS-truthiness, or null when it was absent or falsy. | ||
| /// A null Username means unauthorized. The account is only the one | ||
| /// <c>ValidateCode</c> resolved — the same rule as <see cref="UnreadNotifications"/>. | ||
| /// <paramref name="requestedUser"/> is the body's <c>user</c> field after | ||
| /// JS-truthiness, or null when it was absent or falsy. It does not select the | ||
| /// account. It used to: an unauthenticated caller could pass the guard by naming | ||
| /// any account, and a valid code was then overwritten by that field with no | ||
| /// comparison (ecency/vision-api#90). | ||
| /// | ||
| /// Two rules, both of which were wrong before: | ||
| /// - a validated code is REQUIRED. `requestedUser` used to satisfy the guard on its | ||
| /// own, so an unauthenticated caller could name any account. | ||
| /// - only a SELF view sees the complete feed. Naming another account is still | ||
| /// supported, because Decks builds notification columns for arbitrary accounts and | ||
| /// notifications are largely public, but it is served enotify's restricted feed. | ||
| /// An authorized request is therefore always a self-view, so it may see the | ||
| /// complete feed. A body that names another account still reads the code's | ||
| /// account; it is not a way to ask for someone else's activity. | ||
| /// </summary> | ||
| public static (string? Username, bool FullScope) ResolveNotificationsTarget( | ||
| string? validatedUsername, string? requestedUser) | ||
|
|
@@ -31,20 +33,24 @@ public static (string? Username, bool FullScope) ResolveNotificationsTarget( | |
| return (null, false); | ||
| } | ||
|
|
||
| if (requestedUser == null) | ||
| { | ||
| return (validatedUsername, true); | ||
| } | ||
|
|
||
| return ( | ||
| requestedUser, | ||
| string.Equals(requestedUser, validatedUsername, StringComparison.OrdinalIgnoreCase)); | ||
| // Kept on the signature so a caller can show a body name was supplied, and so | ||
| // a test can fail if that name starts being returned. | ||
| _ = requestedUser; | ||
| return (validatedUsername, true); | ||
|
Comment on lines
+38
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1. Deck columns mislabel notifications ResolveNotificationsTarget now ignores the body's user and returns the validated account with full scope. In vision-web, a notifications deck column sends its selected account as user alongside the signed-in account's code, then displays the returned feed under the selected account's name. Agent Prompt
|
||
| } | ||
|
|
||
| /// <summary>Signed-code validation for the notifications feed, replaceable for tests (no chain RPC).</summary> | ||
| internal static Func<JsonObject, Task<string?>> NotificationsValidateCode = ValidateCode; | ||
|
|
||
| /// <summary>The notifications feed's upstream call, replaceable so tests can observe the path.</summary> | ||
| internal static Func<string, HttpMethod, IEnumerable<KeyValuePair<string, string>>?, Task<UpstreamResponse>> | ||
| NotificationsUpstream = | ||
| (endpoint, method, extraHeaders) => ApiClient.ApiRequest(endpoint, method, extraHeaders); | ||
|
|
||
| /// <summary> | ||
| /// Whether a device request may act on `requestedUsername`. A push registration | ||
| /// belongs to the account the code was issued for, so the device endpoints only | ||
| /// accept that account. Same case rule as ResolveNotificationsTarget. | ||
| /// accept that account. Comparison is case-insensitive, matching Hive names. | ||
| /// </summary> | ||
| public static bool IsOwnDeviceRequest(string? validatedUsername, string? requestedUsername) => | ||
| !string.IsNullOrEmpty(validatedUsername) | ||
|
|
@@ -98,8 +104,9 @@ public static bool IsOwnDeviceRequest(string? validatedUsername, string? request | |
| } | ||
|
|
||
| // Opts in to the complete feed. enotify defaults to chain-derived activity only, | ||
| // so omitting this is the safe direction: a cross-account view, or any request | ||
| // that never reaches this handler, gets the restricted feed. | ||
| // so omitting this is the safe direction: any request that does not ask, | ||
| // including one that never reaches this handler, gets the restricted feed. | ||
| // This handler asks only after a code has validated, and only for that account. | ||
| if (fullScope) | ||
| { | ||
| query.Add("scope=full"); | ||
|
|
@@ -116,8 +123,10 @@ public static async Task Notifications(HttpContext ctx) | |
|
|
||
| // IsTruthy here rather than in the resolver, to keep the JS truthiness parity | ||
| // this port is built on while the decision itself stays pure and testable. | ||
| // The body's user is passed in so the resolver can ignore it on purpose: | ||
| // it must not become the account that is queried. | ||
| var (username, fullScope) = ResolveNotificationsTarget( | ||
| await ValidateCode(body), | ||
| await NotificationsValidateCode(body), | ||
| JsJson.IsTruthy(user) ? UserData1Helpers.Template(user) : null); | ||
|
|
||
| if (username == null) | ||
|
|
@@ -150,7 +159,7 @@ await ValidateCode(body), | |
| ? new[] { new KeyValuePair<string, string>(EnotifyInternalTokenHeader, Config.EnotifyInternalToken) } | ||
| : null; | ||
|
|
||
| await Upstream.Pipe(ApiClient.ApiRequest(u, HttpMethod.Get, extraHeaders), ctx); | ||
| await Upstream.Pipe(NotificationsUpstream(u, HttpMethod.Get, extraHeaders), ctx); | ||
| } | ||
|
|
||
| // GET ^/private-api/pub-notifications/:username | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. Notification changes lack a parity record
📘 Rule violation▣ TestabilityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools