From 30643f1682541fdf7a56cc31723bf93a3a307486 Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sat, 4 Oct 2025 10:09:06 +0200 Subject: [PATCH 1/6] chore: Remove support for get-settings / put-settings that was a brain fart --- README.md | 2 -- src/models/User.ts | 6 ++++-- src/models/User/UserData.ts | 4 ++-- src/services/Fairpost.ts | 5 ++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 17b96d5..a0b449e 100644 --- a/README.md +++ b/README.md @@ -155,8 +155,6 @@ fairpost: @userid refresh-platform --platform=xxx fairpost: @userid refresh-platforms [--platforms=xxx,xxx] fairpost: @userid get-platform --platform=xxx fairpost: @userid get-platforms [--platforms=xxx,xxx] -fairpost: @userid get-settings -fairpost: @userid put-settings fairpost: @userid get-source --source=xxx [--stage=xxx] fairpost: @userid get-sources [--sources=xxx,xxx|--stage=xxx] fairpost: @userid get-post --post=xxx:xxx diff --git a/src/models/User.ts b/src/models/User.ts index 580effc..9b514aa 100644 --- a/src/models/User.ts +++ b/src/models/User.ts @@ -317,10 +317,11 @@ export default class User { /** * @returns all data from the settings store - */ + public getSettings(): { [key: string]: string } { return this.data.getStore("settings"); } + */ public async promptCliFields( fields: FieldMapping, @@ -348,11 +349,12 @@ export default class User { /** * Update settings with values from payload * @param payload - key/value object to save under settings store - */ + public async putSettings(payload: { [key: string]: string }): Promise { for (const key in payload) { this.data.set("settings", key, payload[key]); } await this.data.save(); } + */ } diff --git a/src/models/User/UserData.ts b/src/models/User/UserData.ts index cb8d672..1e59b8e 100644 --- a/src/models/User/UserData.ts +++ b/src/models/User/UserData.ts @@ -77,7 +77,7 @@ export default class UserData { } } - public getStore(storeName: StorageType): { [key: string]: string } { + /*public getStore(storeName: StorageType): { [key: string]: string } { const storageKey = StorageKeys[storeName]; const storage = process.env[storageKey] ?? "none"; const jsonStore = this.jsonData[storeName]; @@ -90,7 +90,7 @@ export default class UserData { "UserData.getStore: Storage " + storage + " not implemented", ); } - } + }*/ public getObject(store: StorageType, key: string, def?: object): object { const value = this.get(store, key, JSON.stringify(def)); diff --git a/src/services/Fairpost.ts b/src/services/Fairpost.ts index efbd632..5c4f1d1 100644 --- a/src/services/Fairpost.ts +++ b/src/services/Fairpost.ts @@ -158,7 +158,7 @@ class Fairpost { break; } - case "get-settings": { + /*case "get-settings": { if (!permissions.manageAccount) { throw new Error("Missing permissions for command " + command); } @@ -186,6 +186,7 @@ class Fairpost { output = { success: true }; break; } + */ case "refresh-token": { if (!permissions.manageAccount) { @@ -939,8 +940,6 @@ class Fairpost { `${cmd} @userid refresh-platforms [--platforms=xxx,xxx]`, `${cmd} @userid get-platform --platform=xxx`, `${cmd} @userid get-platforms [--platforms=xxx,xxx]`, - `${cmd} @userid get-settings`, - `${cmd} @userid put-settings `, `${cmd} @userid get-source --source=xxx [--stage=xxx] `, `${cmd} @userid get-sources [--sources=xxx,xxx|--stage=xxx]`, `${cmd} @userid get-post --post=xxx:xxx`, From 0313c832b8af8c2671cd63ab52dc840dc848ff1d Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sat, 4 Oct 2025 10:26:01 +0200 Subject: [PATCH 2/6] feat: Allow get-platform for inactive platforms --- src/models/User.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/models/User.ts b/src/models/User.ts index 9b514aa..8e4135e 100644 --- a/src/models/User.ts +++ b/src/models/User.ts @@ -242,11 +242,22 @@ export default class User { if (this.platforms === undefined) { this.loadPlatforms(); } - const platform = this.platforms?.[platformId]; - if (!platform) { - throw this.log.error("Unknown or disabled platform: " + platformId); + let platform = this.platforms?.[platformId]; + if (platform) { + return platform; } - return platform; + + Object.values(platformClasses).forEach((platformClass) => { + if (typeof platformClass === "function") { + if (platformClass.id() === platformId) { + platform = new platformClass(this); + } + } + }); + if (platform) { + return platform; + } + throw this.log.error("Unknown platform: " + platformId); } /** From 9744d7209ead3d7ffd05878b76eb1a1b40fc46dd Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sat, 4 Oct 2025 12:07:54 +0200 Subject: [PATCH 3/6] feat: Add support for set-platform --- src/mappers/FeedMapper.ts | 2 +- src/mappers/PlatformMapper.ts | 5 +++-- src/mappers/PostMapper.ts | 2 +- src/mappers/SourceMapper.ts | 2 +- src/mappers/UserMapper.ts | 2 +- src/services/Fairpost.ts | 41 +++++++++++++++++++++++++++++++++++ src/utilities.ts | 8 +------ 7 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/mappers/FeedMapper.ts b/src/mappers/FeedMapper.ts index fcae3c6..b42f5bb 100644 --- a/src/mappers/FeedMapper.ts +++ b/src/mappers/FeedMapper.ts @@ -78,7 +78,7 @@ export default class FeedMapper extends AbstractMapper { async setDto(operator: Operator, dto: FeedDto): Promise { const fields = this.getDtoFields(operator, "set"); for (const field in dto) { - if (field in fields) { + if (fields.includes(field)) { // there are no settable fields } else { throw this.user.log.error("Unknown field: " + field); diff --git a/src/mappers/PlatformMapper.ts b/src/mappers/PlatformMapper.ts index fb891aa..75e0675 100644 --- a/src/mappers/PlatformMapper.ts +++ b/src/mappers/PlatformMapper.ts @@ -110,8 +110,9 @@ export default class PlatformMapper extends AbstractMapper { */ async setDto(operator: Operator, dto: PlatformDto): Promise { const fields = this.getDtoFields(operator, "set"); + console.log(fields); for (const field in dto) { - if (field in fields) { + if (fields.includes(field)) { switch (field) { case "active": if (dto[field]) await this.user.addPlatform(this.platform.id); @@ -149,7 +150,7 @@ export default class PlatformMapper extends AbstractMapper { } } } else { - throw this.user.log.error("Unknown field: " + field); + this.user.log.trace("Ignoring field: " + field); } } await this.user.data.save(); diff --git a/src/mappers/PostMapper.ts b/src/mappers/PostMapper.ts index 37e2052..9a8f17a 100644 --- a/src/mappers/PostMapper.ts +++ b/src/mappers/PostMapper.ts @@ -204,7 +204,7 @@ export default class PostMapper extends AbstractMapper { async setDto(operator: Operator, dto: PostDto): Promise { const fields = this.getDtoFields(operator, "set"); for (const field in dto) { - if (field in fields) { + if (fields.includes(field)) { switch (field) { case "scheduled": this.post.scheduled = new Date((dto.scheduled as string) ?? ""); diff --git a/src/mappers/SourceMapper.ts b/src/mappers/SourceMapper.ts index fbb271b..9afdbc8 100644 --- a/src/mappers/SourceMapper.ts +++ b/src/mappers/SourceMapper.ts @@ -104,7 +104,7 @@ export default class SourceMapper extends AbstractMapper { async setDto(operator: Operator, dto: SourceDto): Promise { const fields = this.getDtoFields(operator, "set"); for (const field in dto) { - if (field in fields) { + if (fields.includes(field)) { switch (field) { // upload here ? case "files": diff --git a/src/mappers/UserMapper.ts b/src/mappers/UserMapper.ts index 9b7f44d..fd4dc65 100644 --- a/src/mappers/UserMapper.ts +++ b/src/mappers/UserMapper.ts @@ -76,7 +76,7 @@ export default class UserMapper extends AbstractMapper { async setDto(operator: Operator, dto: UserDto): Promise { const fields = this.getDtoFields(operator, "set"); for (const field in dto) { - if (field in fields) { + if (fields.includes(field)) { switch (field) { case "id": // todo - there should be a rename-user command instead diff --git a/src/services/Fairpost.ts b/src/services/Fairpost.ts index 5c4f1d1..f13f31d 100644 --- a/src/services/Fairpost.ts +++ b/src/services/Fairpost.ts @@ -323,6 +323,46 @@ class Fairpost { output = await platform.mapper.getDto(operator); break; } + case "set-platform": { + if (!permissions.managePlatforms) { + throw new Error("Missing permissions for command " + command); + } + if (!user) { + throw new Error("user is required for command " + command); + } + if (!args.platform) { + throw user.log.error( + "CommandHandler " + command, + "Missing argument: platform", + ); + } + if (!args.payload) { + throw user.log.error( + "CommandHandler " + command, + "Missing payload", + ); + } + if ( + Buffer.isBuffer(args.payload || typeof args.payload === "string") + ) { + throw user.log.error( + "CommandHandler " + command, + "Payload must be an object", + ); + } + const platform = user.getPlatform(args.platform); + output = { + [args.platform]: { + success: await platform.mapper.setDto( + operator, + args.payload as PlatformDto, + ), + result: await platform.mapper.getDto(operator), + }, + }; + break; + } + case "get-platforms": { if (!permissions.managePlatforms) { throw new Error("Missing permissions for command " + command); @@ -939,6 +979,7 @@ class Fairpost { `${cmd} @userid refresh-platform --platform=xxx`, `${cmd} @userid refresh-platforms [--platforms=xxx,xxx]`, `${cmd} @userid get-platform --platform=xxx`, + `${cmd} @userid put-platform --platform=xxx << platform-dto`, `${cmd} @userid get-platforms [--platforms=xxx,xxx]`, `${cmd} @userid get-source --source=xxx [--stage=xxx] `, `${cmd} @userid get-sources [--sources=xxx,xxx|--stage=xxx]`, diff --git a/src/utilities.ts b/src/utilities.ts index 88837bf..5251d49 100644 --- a/src/utilities.ts +++ b/src/utilities.ts @@ -36,13 +36,7 @@ export async function parsePayload( // Heuristic fallback: Try JSON first try { - const trimmed = str.trim(); - if ( - (trimmed.startsWith("{") && trimmed.endsWith("}")) || - (trimmed.startsWith("[") && trimmed.endsWith("]")) - ) { - return JSON.parse(trimmed); - } + return JSON.parse(str); } catch { // Ignore, not valid JSON } From 515fdaae17b2861f6b071a338b342da18abf7574 Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sat, 4 Oct 2025 12:09:14 +0200 Subject: [PATCH 4/6] feat: Rename setDto to putDto and set-platform to put-platform --- src/mappers/AbstractMapper.ts | 2 +- src/mappers/FeedMapper.ts | 2 +- src/mappers/PlatformMapper.ts | 2 +- src/mappers/PostMapper.ts | 2 +- src/mappers/SourceMapper.ts | 2 +- src/mappers/UserMapper.ts | 2 +- src/services/Fairpost.ts | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mappers/AbstractMapper.ts b/src/mappers/AbstractMapper.ts index 431650a..5b41590 100644 --- a/src/mappers/AbstractMapper.ts +++ b/src/mappers/AbstractMapper.ts @@ -64,7 +64,7 @@ export default abstract class AbstractMapper { * @param dto * @returns boolean success */ - abstract setDto(operator: Operator, dto: ModelDto): Promise; + abstract putDto(operator: Operator, dto: ModelDto): Promise; protected getDtoFields( operator: Operator, diff --git a/src/mappers/FeedMapper.ts b/src/mappers/FeedMapper.ts index b42f5bb..949a213 100644 --- a/src/mappers/FeedMapper.ts +++ b/src/mappers/FeedMapper.ts @@ -75,7 +75,7 @@ export default class FeedMapper extends AbstractMapper { * @param dto * @returns boolean success */ - async setDto(operator: Operator, dto: FeedDto): Promise { + async putDto(operator: Operator, dto: FeedDto): Promise { const fields = this.getDtoFields(operator, "set"); for (const field in dto) { if (fields.includes(field)) { diff --git a/src/mappers/PlatformMapper.ts b/src/mappers/PlatformMapper.ts index 75e0675..a675a1c 100644 --- a/src/mappers/PlatformMapper.ts +++ b/src/mappers/PlatformMapper.ts @@ -108,7 +108,7 @@ export default class PlatformMapper extends AbstractMapper { * @param dto * @returns boolean success */ - async setDto(operator: Operator, dto: PlatformDto): Promise { + async putDto(operator: Operator, dto: PlatformDto): Promise { const fields = this.getDtoFields(operator, "set"); console.log(fields); for (const field in dto) { diff --git a/src/mappers/PostMapper.ts b/src/mappers/PostMapper.ts index 9a8f17a..ca9f13b 100644 --- a/src/mappers/PostMapper.ts +++ b/src/mappers/PostMapper.ts @@ -201,7 +201,7 @@ export default class PostMapper extends AbstractMapper { * @param dto * @returns boolean success */ - async setDto(operator: Operator, dto: PostDto): Promise { + async putDto(operator: Operator, dto: PostDto): Promise { const fields = this.getDtoFields(operator, "set"); for (const field in dto) { if (fields.includes(field)) { diff --git a/src/mappers/SourceMapper.ts b/src/mappers/SourceMapper.ts index 9afdbc8..b8aa539 100644 --- a/src/mappers/SourceMapper.ts +++ b/src/mappers/SourceMapper.ts @@ -101,7 +101,7 @@ export default class SourceMapper extends AbstractMapper { * @param dto * @returns boolean success */ - async setDto(operator: Operator, dto: SourceDto): Promise { + async putDto(operator: Operator, dto: SourceDto): Promise { const fields = this.getDtoFields(operator, "set"); for (const field in dto) { if (fields.includes(field)) { diff --git a/src/mappers/UserMapper.ts b/src/mappers/UserMapper.ts index fd4dc65..4f2d5ce 100644 --- a/src/mappers/UserMapper.ts +++ b/src/mappers/UserMapper.ts @@ -73,7 +73,7 @@ export default class UserMapper extends AbstractMapper { * @param dto * @returns boolean success */ - async setDto(operator: Operator, dto: UserDto): Promise { + async putDto(operator: Operator, dto: UserDto): Promise { const fields = this.getDtoFields(operator, "set"); for (const field in dto) { if (fields.includes(field)) { diff --git a/src/services/Fairpost.ts b/src/services/Fairpost.ts index f13f31d..4fc8d63 100644 --- a/src/services/Fairpost.ts +++ b/src/services/Fairpost.ts @@ -323,7 +323,7 @@ class Fairpost { output = await platform.mapper.getDto(operator); break; } - case "set-platform": { + case "put-platform": { if (!permissions.managePlatforms) { throw new Error("Missing permissions for command " + command); } @@ -353,7 +353,7 @@ class Fairpost { const platform = user.getPlatform(args.platform); output = { [args.platform]: { - success: await platform.mapper.setDto( + success: await platform.mapper.putDto( operator, args.payload as PlatformDto, ), From 0a60045535cb6ac51c64e8b0bc9e7af8c1f738f7 Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sat, 4 Oct 2025 12:11:02 +0200 Subject: [PATCH 5/6] feat: In mappers, ignore unknown fields on put --- src/mappers/FeedMapper.ts | 2 +- src/mappers/PostMapper.ts | 2 +- src/mappers/SourceMapper.ts | 2 +- src/mappers/UserMapper.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mappers/FeedMapper.ts b/src/mappers/FeedMapper.ts index 949a213..0aaf114 100644 --- a/src/mappers/FeedMapper.ts +++ b/src/mappers/FeedMapper.ts @@ -81,7 +81,7 @@ export default class FeedMapper extends AbstractMapper { if (fields.includes(field)) { // there are no settable fields } else { - throw this.user.log.error("Unknown field: " + field); + this.user.log.trace("Ignoring field: " + field); } } return true; diff --git a/src/mappers/PostMapper.ts b/src/mappers/PostMapper.ts index ca9f13b..b1128eb 100644 --- a/src/mappers/PostMapper.ts +++ b/src/mappers/PostMapper.ts @@ -232,7 +232,7 @@ export default class PostMapper extends AbstractMapper { break; } } else { - throw this.user.log.error("Unknown field: " + field); + this.user.log.trace("Ignoring field: " + field); } } return true; diff --git a/src/mappers/SourceMapper.ts b/src/mappers/SourceMapper.ts index b8aa539..7c3a758 100644 --- a/src/mappers/SourceMapper.ts +++ b/src/mappers/SourceMapper.ts @@ -112,7 +112,7 @@ export default class SourceMapper extends AbstractMapper { break; } } else { - throw this.user.log.error("Unknown field: " + field); + this.user.log.trace("Ignoring field: " + field); } } return true; diff --git a/src/mappers/UserMapper.ts b/src/mappers/UserMapper.ts index 4f2d5ce..57baa1e 100644 --- a/src/mappers/UserMapper.ts +++ b/src/mappers/UserMapper.ts @@ -91,7 +91,7 @@ export default class UserMapper extends AbstractMapper { break; } } else { - throw this.user.log.error("Unknown field: " + field); + this.user.log.trace("Ignoring field: " + field); } } await this.user.data.save(); From c3417ad1546f5d0d83457cf6aea1e2912e1b5f76 Mon Sep 17 00:00:00 2001 From: Fairpost Date: Sat, 4 Oct 2025 13:43:12 +0200 Subject: [PATCH 6/6] feat: Add Support for put-platform --- README.md | 5 +++-- src/mappers/PlatformMapper.ts | 1 - src/services/Fairpost.ts | 11 +++++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a0b449e..b960bf0 100644 --- a/README.md +++ b/README.md @@ -148,13 +148,14 @@ to get a new pair of tokens. fairpost: help fairpost: @userid get-user fairpost: @userid get-feed +fairpost: @userid get-platform --platform=xxx +fairpost: @userid put-platform --platform=xxx << payload +fairpost: @userid get-platforms [--platforms=xxx,xxx] fairpost: @userid setup-platform --platform=xxx fairpost: @userid test-platform --platform=xxx fairpost: @userid test-platforms [--platforms=xxx,xxx] fairpost: @userid refresh-platform --platform=xxx fairpost: @userid refresh-platforms [--platforms=xxx,xxx] -fairpost: @userid get-platform --platform=xxx -fairpost: @userid get-platforms [--platforms=xxx,xxx] fairpost: @userid get-source --source=xxx [--stage=xxx] fairpost: @userid get-sources [--sources=xxx,xxx|--stage=xxx] fairpost: @userid get-post --post=xxx:xxx diff --git a/src/mappers/PlatformMapper.ts b/src/mappers/PlatformMapper.ts index a675a1c..a55ab62 100644 --- a/src/mappers/PlatformMapper.ts +++ b/src/mappers/PlatformMapper.ts @@ -110,7 +110,6 @@ export default class PlatformMapper extends AbstractMapper { */ async putDto(operator: Operator, dto: PlatformDto): Promise { const fields = this.getDtoFields(operator, "set"); - console.log(fields); for (const field in dto) { if (fields.includes(field)) { switch (field) { diff --git a/src/services/Fairpost.ts b/src/services/Fairpost.ts index 4fc8d63..5e6bebf 100644 --- a/src/services/Fairpost.ts +++ b/src/services/Fairpost.ts @@ -229,7 +229,7 @@ class Fairpost { break; } - case "add-platform": { + /*case "add-platform": { if (!permissions.manageFeed) { throw new Error("Missing permissions for command " + command); } @@ -273,6 +273,7 @@ class Fairpost { }; break; } + */ case "setup-platform": { if (!permissions.manageFeed) { @@ -971,16 +972,14 @@ class Fairpost { `${cmd} help`, `${cmd} @userid get-user`, `${cmd} @userid get-feed`, - `${cmd} @userid add-platform --platform=xxx`, - `${cmd} @userid remove-platform --platform=xxx`, + `${cmd} @userid get-platform --platform=xxx`, + `${cmd} @userid put-platform --platform=xxx << payload`, + `${cmd} @userid get-platforms [--platforms=xxx,xxx]`, `${cmd} @userid setup-platform --platform=xxx`, `${cmd} @userid test-platform --platform=xxx`, `${cmd} @userid test-platforms [--platforms=xxx,xxx]`, `${cmd} @userid refresh-platform --platform=xxx`, `${cmd} @userid refresh-platforms [--platforms=xxx,xxx]`, - `${cmd} @userid get-platform --platform=xxx`, - `${cmd} @userid put-platform --platform=xxx << platform-dto`, - `${cmd} @userid get-platforms [--platforms=xxx,xxx]`, `${cmd} @userid get-source --source=xxx [--stage=xxx] `, `${cmd} @userid get-sources [--sources=xxx,xxx|--stage=xxx]`, `${cmd} @userid get-post --post=xxx:xxx`,