fix(workshop): use PocketBase name
This commit is contained in:
1 parent
63ad879022
commit
d2d0d16e4d
18 files changed
+71
-85
No files matched your search
@@ -91,8 +91,8 @@ GITHUB_CLIENT_SECRET=...
|
||||
OAuth settings synchronize on every PocketBase startup. Restart after rotation. A production deployment must never
|
||||
supply only one credential. `PB_ALLOWED_ORIGINS=*` is appropriate for the central community because arbitrary
|
||||
self-hosted Homarr origins must open its OAuth popup; a restricted list must include every allowed browser origin.
|
||||
Workshop stores only the OAuth provider username in `users.githubUsername`; users cannot rename it. PocketBase maps
|
||||
**OAuth2 username** to `githubUsername` and leaves the OAuth2 id, full name, and avatar mappings empty. GitHub profiles
|
||||
Workshop stores only the OAuth provider username in `users.name`; users cannot rename it. PocketBase maps
|
||||
**OAuth2 username** to `name` and leaves the OAuth2 id, full name, and avatar mappings empty. GitHub profiles
|
||||
and avatars are derived from `https://github.com/<username>` and `https://github.com/<username>.png`, so no duplicate
|
||||
profile metadata or avatar file is stored.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ onBootstrap((event) => {
|
||||
event.next();
|
||||
const users = event.app.findCollectionByNameOrId("users");
|
||||
users.oauth2.enabled = configured;
|
||||
users.oauth2.mappedFields = { id: "", name: "", username: "githubUsername", avatarURL: "" };
|
||||
users.oauth2.mappedFields = { id: "", name: "", username: "name", avatarURL: "" };
|
||||
users.oauth2.providers = configured ? [{ name: "github", clientId, clientSecret }] : [];
|
||||
event.app.save(users);
|
||||
console.log(JSON.stringify({ event: "workshop_oauth_synchronized", enabled: configured }));
|
||||
@@ -95,7 +95,7 @@ onRecordAfterCreateSuccess((event) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const commenterName = commenter.getString("githubUsername") || "A community member";
|
||||
const commenterName = commenter.getString("name") || "A community member";
|
||||
const submissionTitle = submission.getString("title");
|
||||
const rawExcerpt = event.record.getString("content").slice(0, 280);
|
||||
const submissionUrl = `${publicWorkshopUrl}/${submission.id}/`;
|
||||
@@ -132,7 +132,7 @@ onRecordAfterCreateSuccess((event) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const reporterName = reporter.getString("githubUsername") || "A community member";
|
||||
const reporterName = reporter.getString("name") || "A community member";
|
||||
const submissionTitle = submission.getString("title");
|
||||
const category = event.record.getString("category");
|
||||
const explanation = event.record.getString("explanation");
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
const cloneJson = (value) => JSON.parse(JSON.stringify(value));
|
||||
const cloneRule = (value) => (value === null ? null : String(value));
|
||||
const adminRule = "@request.auth.isAdmin = true";
|
||||
const identityFieldsUnchanged = [
|
||||
"@request.body.email:changed = false",
|
||||
"@request.body.githubUsername:changed = false",
|
||||
].join(" && ");
|
||||
const identityFieldsUnchanged = ["@request.body.email:changed = false", "@request.body.name:changed = false"].join(
|
||||
" && ",
|
||||
);
|
||||
const immutableSubmissionFields = [
|
||||
"@request.body.author:changed = false",
|
||||
"@request.body.type:changed = false",
|
||||
@@ -64,7 +63,7 @@ migrate(
|
||||
};
|
||||
|
||||
users.passwordAuth = { enabled: false };
|
||||
addUserField(new TextField({ name: "githubUsername", required: true, min: 1, max: 39 }));
|
||||
addUserField(new TextField({ name: "name", required: true, min: 1, max: 39 }));
|
||||
addUserField(new BoolField({ name: "isAdmin" }));
|
||||
|
||||
users.listRule = "";
|
||||
@@ -236,7 +235,7 @@ migrate(
|
||||
viewRule: "",
|
||||
viewQuery: `
|
||||
SELECT s.id, s.type, s.title, s.description, s.widgetSchema, s.screenshots, s.author,
|
||||
u.githubUsername AS authorGithubUsername,
|
||||
u.name AS authorName,
|
||||
s.revision, s.changelog, s.outdated, s.created, s.updated,
|
||||
COALESCE((SELECT COUNT(*) FROM votes v WHERE v.submission = s.id AND v.value = 1), 0) AS upvotes,
|
||||
COALESCE((SELECT COUNT(*) FROM votes v WHERE v.submission = s.id AND v.value = -1), 0) AS downvotes,
|
||||
|
||||
@@ -24,7 +24,7 @@ if (!users.oauth2?.enabled || github?.clientId !== expectedClientId) {
|
||||
throw new Error(`GitHub OAuth was not synchronized for ${expectedClientId}`);
|
||||
}
|
||||
if (
|
||||
users.oauth2?.mappedFields?.username !== "githubUsername" ||
|
||||
users.oauth2?.mappedFields?.username !== "name" ||
|
||||
users.oauth2?.mappedFields?.id ||
|
||||
users.oauth2?.mappedFields?.name ||
|
||||
users.oauth2?.mappedFields?.avatarURL
|
||||
|
||||
@@ -15,7 +15,7 @@ if (!hook.includes("require(`${__hooks}/workshop-utils.js`)")) {
|
||||
if (!hook.includes("onBootstrap") || !hook.includes("users.oauth2.providers = configured")) {
|
||||
throw new Error("Workshop OAuth settings must be synchronized at every bootstrap");
|
||||
}
|
||||
if (!hook.includes('username: "githubUsername"') || hook.includes("onRecordAuthWithOAuth2Request")) {
|
||||
if (!hook.includes('username: "name"') || hook.includes("onRecordAuthWithOAuth2Request")) {
|
||||
throw new Error("Workshop identity must use PocketBase's direct GitHub username mapping");
|
||||
}
|
||||
if (hook.includes("validateAndNormalizeSubmission")) {
|
||||
@@ -41,7 +41,7 @@ if (hook.includes('findAllRecords("users")') || !hook.includes('findRecordsByFil
|
||||
}
|
||||
|
||||
const migration = await read("apps/workshop/pb_migrations/1784240000_workshop_widgets.js");
|
||||
for (const removedField of ["displayName", "avatarUrl", "githubProfileUrl"]) {
|
||||
for (const removedField of ["displayName", "avatarUrl", "githubProfileUrl", "githubUsername"]) {
|
||||
if (migration.includes(removedField)) throw new Error(`Redundant Workshop user field remains: ${removedField}`);
|
||||
}
|
||||
for (const required of [
|
||||
|
||||
@@ -46,7 +46,7 @@ await request("/api/collections/users", {
|
||||
body: JSON.stringify({ ...usersCollection, passwordAuth: { enabled: true, identityFields: ["email"] } }),
|
||||
});
|
||||
|
||||
const createUser = async (email, githubUsername, password, extra = {}) =>
|
||||
const createUser = async (email, name, password, extra = {}) =>
|
||||
request("/api/collections/users/records", {
|
||||
method: "POST",
|
||||
headers: rootHeaders,
|
||||
@@ -56,7 +56,7 @@ const createUser = async (email, githubUsername, password, extra = {}) =>
|
||||
verified: true,
|
||||
password,
|
||||
passwordConfirm: password,
|
||||
githubUsername,
|
||||
name,
|
||||
...extra,
|
||||
}),
|
||||
});
|
||||
@@ -79,13 +79,13 @@ await expectStatus(
|
||||
);
|
||||
await expectStatus(
|
||||
`/api/collections/users/records/${author.id}`,
|
||||
{ method: "PATCH", headers: authorSession.headers, body: JSON.stringify({ githubUsername: "homarr-labs" }) },
|
||||
{ method: "PATCH", headers: authorSession.headers, body: JSON.stringify({ name: "homarr-labs" }) },
|
||||
404,
|
||||
);
|
||||
const unchangedAuthor = await request(`/api/collections/users/records/${author.id}`, {
|
||||
headers: authorSession.headers,
|
||||
});
|
||||
if (unchangedAuthor.githubUsername !== "widget-author") {
|
||||
if (unchangedAuthor.name !== "widget-author") {
|
||||
throw new Error("Workshop users can forge OAuth provider identity fields");
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ if (
|
||||
listing.score !== 2 ||
|
||||
listing.upvotes !== 2 ||
|
||||
listing.downvotes !== 0 ||
|
||||
listing.authorGithubUsername !== "widget-author" ||
|
||||
listing.authorName !== "widget-author" ||
|
||||
listing.widgetSchema !== widget.$schema
|
||||
) {
|
||||
throw new Error("Workshop listing data is incorrect");
|
||||
@@ -232,7 +232,7 @@ const comment = await request("/api/collections/comments/records?expand=author",
|
||||
headers: visitorSession.headers,
|
||||
body: JSON.stringify({ submission: submission.id, author: visitor.id, content: "Useful widget" }),
|
||||
});
|
||||
if (comment.author !== visitor.id || comment.expand.author.githubUsername !== "widget-visitor") {
|
||||
if (comment.author !== visitor.id || comment.expand.author.name !== "widget-visitor") {
|
||||
throw new Error("Comment author expansion is incorrect");
|
||||
}
|
||||
await expectStatus(
|
||||
|
||||
Reference in new issue
Block a user