diff --git a/README.md b/README.md index 17b96d5..b960bf0 100644 --- a/README.md +++ b/README.md @@ -148,15 +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-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/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 fcae3c6..0aaf114 100644 --- a/src/mappers/FeedMapper.ts +++ b/src/mappers/FeedMapper.ts @@ -75,13 +75,13 @@ 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 (field in fields) { + 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/PlatformMapper.ts b/src/mappers/PlatformMapper.ts index fb891aa..a55ab62 100644 --- a/src/mappers/PlatformMapper.ts +++ b/src/mappers/PlatformMapper.ts @@ -108,10 +108,10 @@ 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"); 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 +149,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..b1128eb 100644 --- a/src/mappers/PostMapper.ts +++ b/src/mappers/PostMapper.ts @@ -201,10 +201,10 @@ 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 (field in fields) { + if (fields.includes(field)) { switch (field) { case "scheduled": this.post.scheduled = new Date((dto.scheduled as string) ?? ""); @@ -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 fbb271b..7c3a758 100644 --- a/src/mappers/SourceMapper.ts +++ b/src/mappers/SourceMapper.ts @@ -101,10 +101,10 @@ 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 (field in fields) { + if (fields.includes(field)) { switch (field) { // upload here ? case "files": @@ -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 9b7f44d..57baa1e 100644 --- a/src/mappers/UserMapper.ts +++ b/src/mappers/UserMapper.ts @@ -73,10 +73,10 @@ 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 (field in fields) { + if (fields.includes(field)) { switch (field) { case "id": // todo - there should be a rename-user command instead @@ -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(); diff --git a/src/models/User.ts b/src/models/User.ts index 580effc..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); } /** @@ -317,10 +328,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 +360,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..5e6bebf 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) { @@ -228,7 +229,7 @@ class Fairpost { break; } - case "add-platform": { + /*case "add-platform": { if (!permissions.manageFeed) { throw new Error("Missing permissions for command " + command); } @@ -272,6 +273,7 @@ class Fairpost { }; break; } + */ case "setup-platform": { if (!permissions.manageFeed) { @@ -322,6 +324,46 @@ class Fairpost { output = await platform.mapper.getDto(operator); break; } + case "put-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.putDto( + 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); @@ -930,17 +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 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`, 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 }