@happyvertical/smrt-social 0.54.2 → 0.54.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +6 -2
- package/dist/collections/oauth-state-collection.d.ts +10 -0
- package/dist/collections/oauth-state-collection.d.ts.map +1 -1
- package/dist/index.js +63 -2
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +60 -6
- package/dist/oauth-state.d.ts +27 -0
- package/dist/oauth-state.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +61 -9
- package/package.json +12 -12
package/dist/oauth-state.d.ts
CHANGED
|
@@ -39,6 +39,14 @@ export interface OAuthStateOptions extends SmrtObjectOptions {
|
|
|
39
39
|
* Tenant ID for multi-tenant isolation
|
|
40
40
|
*/
|
|
41
41
|
tenantId?: string | null;
|
|
42
|
+
/**
|
|
43
|
+
* User who started the OAuth flow
|
|
44
|
+
*/
|
|
45
|
+
createdByUserId?: string | null;
|
|
46
|
+
/**
|
|
47
|
+
* Application-defined path to return to after the callback
|
|
48
|
+
*/
|
|
49
|
+
returnTo?: string | null;
|
|
42
50
|
}
|
|
43
51
|
/**
|
|
44
52
|
* Temporary OAuth state for social account connection
|
|
@@ -47,6 +55,9 @@ export interface OAuthStateOptions extends SmrtObjectOptions {
|
|
|
47
55
|
* - Verify callback requests match initiated requests (CSRF protection)
|
|
48
56
|
* - Store PKCE code verifier for code exchange
|
|
49
57
|
* - Track redirect URI and scopes for verification
|
|
58
|
+
* - Bind the flow to the user who started it (`createdByUserId`) and record
|
|
59
|
+
* where the host returns afterwards (`returnTo`), so one fixed callback
|
|
60
|
+
* can serve every tenant
|
|
50
61
|
*
|
|
51
62
|
* These records should be cleaned up after successful connection
|
|
52
63
|
* or after expiration.
|
|
@@ -103,6 +114,22 @@ export declare class OAuthState extends SmrtObject {
|
|
|
103
114
|
* States should be short-lived (10 minutes typical)
|
|
104
115
|
*/
|
|
105
116
|
expiresAt: Date;
|
|
117
|
+
/**
|
|
118
|
+
* User who started the OAuth flow.
|
|
119
|
+
*
|
|
120
|
+
* A host with one fixed callback for every tenant compares this to the
|
|
121
|
+
* signed-in user on callback and rejects a mismatch, so a forwarded or
|
|
122
|
+
* leaked state cannot be completed by someone else. A `@crossPackageRef` to
|
|
123
|
+
* `@happyvertical/smrt-users:User` (native uuid on PostgreSQL, no DDL FK).
|
|
124
|
+
* Null for states created before the column existed.
|
|
125
|
+
*/
|
|
126
|
+
createdByUserId: string | null;
|
|
127
|
+
/**
|
|
128
|
+
* Application-defined path to return to after the callback, for example the
|
|
129
|
+
* settings page that started the flow. Opaque to the framework: the host
|
|
130
|
+
* that reads it must validate it as a same-origin path before redirecting.
|
|
131
|
+
*/
|
|
132
|
+
returnTo: string | null;
|
|
106
133
|
constructor(options?: OAuthStateOptions);
|
|
107
134
|
/**
|
|
108
135
|
* Check if the state has expired
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-state.d.ts","sourceRoot":"","sources":["../src/oauth-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,
|
|
1
|
+
{"version":3,"file":"oauth-state.d.ts","sourceRoot":"","sources":["../src/oauth-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAmB,UAAU,EAAQ,MAAM,0BAA0B,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D;;OAEG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAE9B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,IAAI,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBASa,UAAW,SAAQ,UAAU;IACxC;;OAEG;IAEH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B;;OAEG;IACH,QAAQ,EAAE,kBAAkB,CAAa;IAEzC;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAM;IAEnB;;;OAGG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEnC;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAM;IAEzB;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAM;IAEtB;;;OAGG;IACH,SAAS,EAAE,IAAI,CAAyC;IAExD;;;;;;;;OAQG;IAEH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEtC;;;;OAIG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;gBAEnB,OAAO,GAAE,iBAAsB;IAiB3C;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO;IAI3C;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,MAAM;IAI9B;;;OAGG;IACH,MAAM,CAAC,oBAAoB,IAAI,MAAM;IAQrC;;;OAGG;WACU,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAOtE"}
|
package/dist/smrt-knowledge.json
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
"sensitiveFieldsExcluded": true,
|
|
4
4
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
5
5
|
"packageName": "@happyvertical/smrt-social",
|
|
6
|
-
"packageVersion": "0.54.
|
|
6
|
+
"packageVersion": "0.54.4",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
12
|
-
"agents": "
|
|
10
|
+
"manifest": "5d2b297b125dab894da7115d298875e7b293085967791ef4a5358104a0d1d5e9",
|
|
11
|
+
"packageJson": "5f6e97155301e69b9fece15031f57273ccf4db421668b3916005910a1a28aa54",
|
|
12
|
+
"agents": "7596f706e6513fd86254f510301ec9696520655bdf19f932ec2267ca9d5767ee"
|
|
13
13
|
},
|
|
14
14
|
"exports": [
|
|
15
15
|
".",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"youtube"
|
|
65
65
|
],
|
|
66
66
|
"risks": [
|
|
67
|
-
"cross-package-refs:
|
|
67
|
+
"cross-package-refs:4",
|
|
68
68
|
"sensitive-fields-excluded",
|
|
69
69
|
"sti-inheritance"
|
|
70
70
|
],
|
|
@@ -134,9 +134,30 @@
|
|
|
134
134
|
"type": "datetime",
|
|
135
135
|
"required": false,
|
|
136
136
|
"columnType": "TIMESTAMP"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"name": "createdByUserId",
|
|
140
|
+
"type": "crossPackageRef",
|
|
141
|
+
"required": false,
|
|
142
|
+
"related": "@happyvertical/smrt-users:User",
|
|
143
|
+
"columnType": "UUID"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"name": "returnTo",
|
|
147
|
+
"type": "text",
|
|
148
|
+
"required": false,
|
|
149
|
+
"columnType": "TEXT"
|
|
150
|
+
}
|
|
151
|
+
],
|
|
152
|
+
"relationships": [
|
|
153
|
+
{
|
|
154
|
+
"name": "createdByUserId",
|
|
155
|
+
"type": "crossPackageRef",
|
|
156
|
+
"required": false,
|
|
157
|
+
"related": "@happyvertical/smrt-users:User",
|
|
158
|
+
"columnType": "UUID"
|
|
137
159
|
}
|
|
138
160
|
],
|
|
139
|
-
"relationships": [],
|
|
140
161
|
"methods": [
|
|
141
162
|
"generateCodeChallenge",
|
|
142
163
|
"generateCodeVerifier",
|
|
@@ -302,6 +323,7 @@
|
|
|
302
323
|
}
|
|
303
324
|
],
|
|
304
325
|
"relationshipFeatures": [
|
|
326
|
+
"crossPackageRef",
|
|
305
327
|
"uuidColumns"
|
|
306
328
|
],
|
|
307
329
|
"tags": [],
|
|
@@ -1079,11 +1101,20 @@
|
|
|
1079
1101
|
"fields": [],
|
|
1080
1102
|
"relationships": [],
|
|
1081
1103
|
"methods": [
|
|
1104
|
+
"consume",
|
|
1082
1105
|
"deleteExpired",
|
|
1083
1106
|
"findByState",
|
|
1084
1107
|
"findExpired"
|
|
1085
1108
|
],
|
|
1086
1109
|
"methodSignatures": [
|
|
1110
|
+
{
|
|
1111
|
+
"name": "consume",
|
|
1112
|
+
"async": true,
|
|
1113
|
+
"params": [
|
|
1114
|
+
"state: OAuthState"
|
|
1115
|
+
],
|
|
1116
|
+
"returns": "Promise<boolean>"
|
|
1117
|
+
},
|
|
1087
1118
|
{
|
|
1088
1119
|
"name": "deleteExpired",
|
|
1089
1120
|
"async": true,
|
|
@@ -1140,6 +1171,12 @@
|
|
|
1140
1171
|
"operation": "findByState",
|
|
1141
1172
|
"objectName": "@happyvertical/smrt-social:OAuthStateCollection"
|
|
1142
1173
|
},
|
|
1174
|
+
{
|
|
1175
|
+
"kind": "cli",
|
|
1176
|
+
"name": "oauthstatecollection_consume",
|
|
1177
|
+
"operation": "consume",
|
|
1178
|
+
"objectName": "@happyvertical/smrt-social:OAuthStateCollection"
|
|
1179
|
+
},
|
|
1143
1180
|
{
|
|
1144
1181
|
"kind": "cli",
|
|
1145
1182
|
"name": "oauthstatecollection_findExpired",
|
|
@@ -1153,6 +1190,15 @@
|
|
|
1153
1190
|
"objectName": "@happyvertical/smrt-social:OAuthStateCollection"
|
|
1154
1191
|
}
|
|
1155
1192
|
],
|
|
1193
|
+
"withheldSurfaces": [
|
|
1194
|
+
{
|
|
1195
|
+
"kind": "api",
|
|
1196
|
+
"operation": "consume",
|
|
1197
|
+
"code": "not-wireable",
|
|
1198
|
+
"reason": "not routed: parameter `state`: `OAuthState` is a model class instance, not JSON data",
|
|
1199
|
+
"objectName": "@happyvertical/smrt-social:OAuthStateCollection"
|
|
1200
|
+
}
|
|
1201
|
+
],
|
|
1156
1202
|
"relationshipFeatures": [
|
|
1157
1203
|
"uuidColumns"
|
|
1158
1204
|
],
|
|
@@ -1968,6 +2014,12 @@
|
|
|
1968
2014
|
"operation": "findByState",
|
|
1969
2015
|
"objectName": "@happyvertical/smrt-social:OAuthStateCollection"
|
|
1970
2016
|
},
|
|
2017
|
+
{
|
|
2018
|
+
"kind": "cli",
|
|
2019
|
+
"name": "oauthstatecollection_consume",
|
|
2020
|
+
"operation": "consume",
|
|
2021
|
+
"objectName": "@happyvertical/smrt-social:OAuthStateCollection"
|
|
2022
|
+
},
|
|
1971
2023
|
{
|
|
1972
2024
|
"kind": "cli",
|
|
1973
2025
|
"name": "oauthstatecollection_findExpired",
|
|
@@ -2212,11 +2264,11 @@
|
|
|
2212
2264
|
"prompts": [],
|
|
2213
2265
|
"relationshipsV2": {
|
|
2214
2266
|
"foreignKeyFields": 2,
|
|
2215
|
-
"crossPackageRefFields":
|
|
2267
|
+
"crossPackageRefFields": 4,
|
|
2216
2268
|
"junctionCollections": 0,
|
|
2217
2269
|
"hierarchicalObjects": 0,
|
|
2218
2270
|
"polymorphicAssociations": 0,
|
|
2219
|
-
"uuidColumns":
|
|
2271
|
+
"uuidColumns": 28
|
|
2220
2272
|
},
|
|
2221
|
-
"agentDoc": "# @happyvertical/smrt-social\n\nSocial media account management with OAuth and post scheduling. Supports YouTube, Threads, X (Twitter), Bluesky.\n\n## Models\n\n- **SocialAccount** (STI): `platform`, `accessToken`/`refreshToken`, `tokenExpiresAt`, `status` (connected/expired/error), `linkBehavior` (description/reply/none). `isTokenExpired` checks with 5-min buffer. `isReady` gate checks active + connected + token present + not expired.\n- **SocialPost**: `scheduledAt`, `publishedAt`, `status` (draft/scheduled/publishing/published/failed), `analytics` JSON (views/likes/comments/shares/clicks). `createdByUserId` (nullable `@crossPackageRef` to `smrt-users:User`, uuid on PostgreSQL) records the poster; pass it to `createDraft()` so a failed publish can be reported to that person. Agent/schedule posts leave it null; `recordPublishSuccess`/`Failure` never change it. Adding the column is additive: consumers run `db:migrate`.\n- **OAuthState** (STI): CSRF token + PKCE `codeVerifier` with 10-min TTL
|
|
2273
|
+
"agentDoc": "# @happyvertical/smrt-social\n\nSocial media account management with OAuth and post scheduling. Supports YouTube, Threads, X (Twitter), Bluesky.\n\n## Models\n\n- **SocialAccount** (STI): `platform`, `accessToken`/`refreshToken`, `tokenExpiresAt`, `status` (connected/expired/error), `linkBehavior` (description/reply/none). `isTokenExpired` checks with 5-min buffer. `isReady` gate checks active + connected + token present + not expired.\n- **SocialPost**: `scheduledAt`, `publishedAt`, `status` (draft/scheduled/publishing/published/failed), `analytics` JSON (views/likes/comments/shares/clicks). `createdByUserId` (nullable `@crossPackageRef` to `smrt-users:User`, uuid on PostgreSQL) records the poster; pass it to `createDraft()` so a failed publish can be reported to that person. Agent/schedule posts leave it null; `recordPublishSuccess`/`Failure` never change it. Adding the column is additive: consumers run `db:migrate`.\n- **OAuthState** (STI): CSRF token + PKCE `codeVerifier` with 10-min TTL. `createdByUserId` (nullable `@crossPackageRef` to `smrt-users:User`) binds the flow to its initiator and `returnTo` stores an opaque host path; a host with one fixed callback for every tenant must reject a different user and validate `returnTo` as same-origin. `OAuthStateCollection.consume(state)` is the single-use arbiter (revision-guarded delete; `false` when another caller already consumed it). Both columns are additive: consumers run `db:migrate`.\n\n## Gotchas\n\n- **Tokens not encrypted**: OAuth tokens stored as plaintext — TODO for smrt-secrets integration\n- **No auto-publishing**: `scheduledAt` is metadata only — app must implement job runner to trigger publishing\n- **Analytics manual**: `analytics` field must be updated by platform sync, not auto-populated\n- **Platform enum hardcoded**: youtube/threads/x/bluesky — extending requires code changes\n- **OAuthState TTL**: 10 minutes, app must clean up expired states\n- **Optional tenancy** on all models\n- **Relationship targets**: `SocialPost.socialAccountId` and\n `SocialPostAnalyticsSnapshot.socialPostId` are same-package `@foreignKey`\n columns; `SocialPost.videoContentId` is a `@crossPackageRef` to\n `@happyvertical/smrt-video:VideoContent` (no value import back into this\n package). They previously used `@foreignKey(() => X)`, whose target resolved\n to `''`, so none of them carried a relationship edge (#2379).\n"
|
|
2222
2274
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-social",
|
|
3
|
-
"version": "0.54.
|
|
3
|
+
"version": "0.54.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"smrtRawPrimitives": "strict",
|
|
6
6
|
"description": "Social media account management for multi-platform publishing in the SMRT ecosystem",
|
|
@@ -39,19 +39,19 @@
|
|
|
39
39
|
"AGENTS.md"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@happyvertical/smrt-config": "0.54.
|
|
43
|
-
"@happyvertical/smrt-content": "0.54.
|
|
44
|
-
"@happyvertical/smrt-core": "0.54.
|
|
45
|
-
"@happyvertical/smrt-secrets": "0.54.
|
|
46
|
-
"@happyvertical/smrt-tenancy": "0.54.
|
|
47
|
-
"@happyvertical/smrt-ui": "0.54.
|
|
48
|
-
"@happyvertical/smrt-video": "0.54.
|
|
49
|
-
"@happyvertical/utils": "^0.
|
|
42
|
+
"@happyvertical/smrt-config": "0.54.4",
|
|
43
|
+
"@happyvertical/smrt-content": "0.54.4",
|
|
44
|
+
"@happyvertical/smrt-core": "0.54.4",
|
|
45
|
+
"@happyvertical/smrt-secrets": "0.54.4",
|
|
46
|
+
"@happyvertical/smrt-tenancy": "0.54.4",
|
|
47
|
+
"@happyvertical/smrt-ui": "0.54.4",
|
|
48
|
+
"@happyvertical/smrt-video": "0.54.4",
|
|
49
|
+
"@happyvertical/utils": "^0.102.1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@happyvertical/logger": "^0.
|
|
53
|
-
"@happyvertical/smrt-vitest": "0.54.
|
|
54
|
-
"@happyvertical/sql": "^0.
|
|
52
|
+
"@happyvertical/logger": "^0.102.1",
|
|
53
|
+
"@happyvertical/smrt-vitest": "0.54.4",
|
|
54
|
+
"@happyvertical/sql": "^0.102.1",
|
|
55
55
|
"@sveltejs/package": "^2.5.8",
|
|
56
56
|
"@types/node": "24.13.6",
|
|
57
57
|
"svelte": "^5.57.1",
|