mirror of
https://github.com/TautvydasDerzinskas/Thingport.git
synced 2026-10-21 06:09:56 -05:00
fix: correct category updates and improve NexPrint error handling
This commit is contained in:
1 parent
4037151e4a
commit
1cf2903b8e
6 files changed
+30
-14
No files matched your search
@@ -185,6 +185,12 @@ function parseCatIdsInput(raw: string | null | undefined): number[] {
|
||||
}
|
||||
|
||||
const catIdsField = z.string().trim().max(1000).nullable().optional();
|
||||
|
||||
/** A field the request leaves out is left as it is (Prisma skips undefined), so a client from before a provider was
|
||||
* added can't wipe that provider's ids; blank or null still clears them. */
|
||||
function catIdsUpdate(raw: string | null | undefined): number[] | undefined {
|
||||
return raw === undefined ? undefined : parseCatIdsInput(raw);
|
||||
}
|
||||
const categoryMetaSchema = z.object({
|
||||
meta_title: z.string().trim().max(200).nullable().optional(),
|
||||
meta_description: z.string().trim().max(2000).nullable().optional(),
|
||||
@@ -209,14 +215,14 @@ router.patch(
|
||||
data: {
|
||||
metaTitle: body.meta_title || null,
|
||||
metaDescription: body.meta_description || null,
|
||||
makerworldCatIds: parseCatIdsInput(body.makerworld_cat_ids),
|
||||
thingiverseCatIds: parseCatIdsInput(body.thingiverse_cat_ids),
|
||||
printablesCatIds: parseCatIdsInput(body.printables_cat_ids),
|
||||
myminifactoryCatIds: parseCatIdsInput(body.myminifactory_cat_ids),
|
||||
snapmakerCatIds: parseCatIdsInput(body.snapmaker_cat_ids),
|
||||
makeronlineCatIds: parseCatIdsInput(body.makeronline_cat_ids),
|
||||
crealitycloudCatIds: parseCatIdsInput(body.crealitycloud_cat_ids),
|
||||
nexprintCatIds: parseCatIdsInput(body.nexprint_cat_ids).map(String),
|
||||
makerworldCatIds: catIdsUpdate(body.makerworld_cat_ids),
|
||||
thingiverseCatIds: catIdsUpdate(body.thingiverse_cat_ids),
|
||||
printablesCatIds: catIdsUpdate(body.printables_cat_ids),
|
||||
myminifactoryCatIds: catIdsUpdate(body.myminifactory_cat_ids),
|
||||
snapmakerCatIds: catIdsUpdate(body.snapmaker_cat_ids),
|
||||
makeronlineCatIds: catIdsUpdate(body.makeronline_cat_ids),
|
||||
crealitycloudCatIds: catIdsUpdate(body.crealitycloud_cat_ids),
|
||||
nexprintCatIds: catIdsUpdate(body.nexprint_cat_ids)?.map(String),
|
||||
},
|
||||
});
|
||||
res.json(toCategoryOut(updated));
|
||||
|
||||
@@ -174,8 +174,9 @@ export async function fetchListing(
|
||||
return listing ? listing.entries.map((e) => e.modelId) : null;
|
||||
}
|
||||
if (sync.provider === "nexprint") {
|
||||
// Collections, the private ones too, list without a sign-in; only their files need one.
|
||||
const listing = await fetchNexprintCollection(id);
|
||||
// Collections, the private ones too, list without a sign-in; only their files need one. All of it, not the import
|
||||
// dialog's first 600, or models past those would never be found.
|
||||
const listing = await fetchNexprintCollection(id, Number.POSITIVE_INFINITY);
|
||||
return listing ? listing.entries.map((e) => e.modelId) : null;
|
||||
}
|
||||
throw new Error(`Unknown provider "${sync.provider}"`);
|
||||
|
||||
@@ -154,7 +154,9 @@ export async function checkNexprintAuth(
|
||||
try {
|
||||
const { code, data } = await fetchApi("/model-user-server/member/user_data", { body: {} }, token);
|
||||
const user = isRecord(data) && isRecord(data.userData) ? data.userData : null;
|
||||
if (code !== CODE_OK || !user || !outId(user.userId, "U")) return code === null ? "unreachable" : "rejected";
|
||||
// Only a refusal says the token is bad; any other error code is NexPrint's own trouble.
|
||||
if (code !== CODE_OK) return code === CODE_UNAUTHORIZED ? "rejected" : "unreachable";
|
||||
if (!user || !outId(user.userId, "U")) return "rejected";
|
||||
return { userId: outId(user.userId, "U")!, name: str(user.nickname) };
|
||||
} catch (err) {
|
||||
return err instanceof NexprintAuthError ? "rejected" : "unreachable";
|
||||
|
||||
@@ -124,6 +124,10 @@ describe("NexPrint sign-in", () => {
|
||||
|
||||
stubApi({ "/model-user-server/member/user_data": () => apiResponse(401, null, "账号未登录") });
|
||||
expect(await checkNexprintAuth(TOKEN)).toBe("rejected");
|
||||
|
||||
// Its own trouble isn't the token's fault.
|
||||
stubApi({ "/model-user-server/member/user_data": () => apiResponse(500, null, "系统繁忙") });
|
||||
expect(await checkNexprintAuth(TOKEN)).toBe("unreachable");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ from Thingport Grab wait in **Administration → Import queue** until they're st
|
||||
|
||||
Printables works with no setup. MakerWorld needs your session cookie, and Thingiverse and MyMiniFactory a key set by an
|
||||
admin; MyMiniFactory models you bought come in once you connect your MyMiniFactory account. Snapmaker Space needs your
|
||||
own sign-in, which Thingport Grab keeps fresh, MakerOnline Thingport Grab for its files, and Creality Cloud and NexPrint your own
|
||||
sign-in, which Grab sends on when you visit them. See
|
||||
own sign-in, which Thingport Grab keeps fresh; MakerOnline's files come only through Thingport Grab; and Creality Cloud
|
||||
and NexPrint need your own sign-in, which Grab sends to Thingport when you visit them. See
|
||||
[provider setup](../PROVIDER_SETUP.md). Admins can also
|
||||
[turn a provider off](../PROVIDER_SETUP.md#turning-a-provider-off) for the whole instance, and then nothing is imported
|
||||
from it.
|
||||
|
||||
@@ -20,7 +20,10 @@ export async function syncNexprintSession(): Promise<void> {
|
||||
// Per Thingport account, so switching the extension to another one sends it there too.
|
||||
const account = `${config.instanceUrl} ${config.email}`;
|
||||
const last = config.lastSyncedNexprintSession;
|
||||
const token = cookie?.value ? decodeURIComponent(cookie.value) : "";
|
||||
let token = "";
|
||||
try {
|
||||
token = cookie?.value ? decodeURIComponent(cookie.value) : "";
|
||||
} catch {} // Malformed percent-encoding: not a token.
|
||||
// Signed out, the site clears the cookie or leaves a placeholder in it.
|
||||
if (!/^[0-9a-f]{32,128}$/i.test(token)) {
|
||||
// Clear the sign-in Grab sent, but not one pasted in Thingport.
|
||||
|
||||
Reference in new issue
Block a user