@oxyhq/core 3.1.0 → 3.4.0

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.
Files changed (74) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/AuthManager.js +14 -3
  3. package/dist/cjs/HttpService.js +89 -0
  4. package/dist/cjs/OxyServices.js +2 -1
  5. package/dist/cjs/constants/version.js +1 -1
  6. package/dist/cjs/i18n/locales/en-US.json +44 -44
  7. package/dist/cjs/i18n/locales/es-ES.json +44 -44
  8. package/dist/cjs/i18n/locales/locales/en-US.json +44 -44
  9. package/dist/cjs/i18n/locales/locales/es-ES.json +44 -44
  10. package/dist/cjs/index.js +4 -0
  11. package/dist/cjs/mixins/OxyServices.applications.js +33 -3
  12. package/dist/cjs/mixins/OxyServices.reputation.js +244 -0
  13. package/dist/cjs/mixins/OxyServices.workspaces.js +146 -0
  14. package/dist/cjs/mixins/index.js +4 -2
  15. package/dist/cjs/utils/accountUtils.js +12 -5
  16. package/dist/cjs/utils/ssoReturn.js +80 -33
  17. package/dist/esm/.tsbuildinfo +1 -1
  18. package/dist/esm/AuthManager.js +14 -3
  19. package/dist/esm/HttpService.js +89 -0
  20. package/dist/esm/OxyServices.js +2 -1
  21. package/dist/esm/constants/version.js +1 -1
  22. package/dist/esm/i18n/locales/en-US.json +44 -44
  23. package/dist/esm/i18n/locales/es-ES.json +44 -44
  24. package/dist/esm/i18n/locales/locales/en-US.json +44 -44
  25. package/dist/esm/i18n/locales/locales/es-ES.json +44 -44
  26. package/dist/esm/index.js +4 -0
  27. package/dist/esm/mixins/OxyServices.applications.js +33 -3
  28. package/dist/esm/mixins/OxyServices.reputation.js +241 -0
  29. package/dist/esm/mixins/OxyServices.workspaces.js +143 -0
  30. package/dist/esm/mixins/index.js +4 -2
  31. package/dist/esm/utils/accountUtils.js +12 -5
  32. package/dist/esm/utils/ssoReturn.js +80 -33
  33. package/dist/types/.tsbuildinfo +1 -1
  34. package/dist/types/HttpService.d.ts +57 -0
  35. package/dist/types/OxyServices.d.ts +2 -1
  36. package/dist/types/constants/version.d.ts +2 -2
  37. package/dist/types/index.d.ts +4 -2
  38. package/dist/types/mixins/OxyServices.applications.d.ts +86 -10
  39. package/dist/types/mixins/OxyServices.features.d.ts +0 -1
  40. package/dist/types/mixins/OxyServices.reputation.d.ts +436 -0
  41. package/dist/types/mixins/OxyServices.workspaces.d.ts +205 -0
  42. package/dist/types/mixins/index.d.ts +3 -2
  43. package/dist/types/models/interfaces.d.ts +24 -26
  44. package/dist/types/utils/accountUtils.d.ts +17 -4
  45. package/dist/types/utils/ssoReturn.d.ts +30 -9
  46. package/package.json +2 -1
  47. package/src/AuthManager.ts +14 -3
  48. package/src/HttpService.ts +91 -0
  49. package/src/OxyServices.ts +2 -1
  50. package/src/__tests__/authManager.cookiePath.test.ts +49 -0
  51. package/src/__tests__/httpServiceCache.test.ts +198 -0
  52. package/src/constants/version.ts +1 -1
  53. package/src/i18n/locales/en-US.json +44 -44
  54. package/src/i18n/locales/es-ES.json +44 -44
  55. package/src/index.ts +51 -4
  56. package/src/mixins/OxyServices.applications.ts +103 -5
  57. package/src/mixins/OxyServices.auth.ts +2 -1
  58. package/src/mixins/OxyServices.features.ts +0 -1
  59. package/src/mixins/OxyServices.reputation.ts +674 -0
  60. package/src/mixins/OxyServices.workspaces.ts +315 -0
  61. package/src/mixins/__tests__/reputation.test.ts +408 -0
  62. package/src/mixins/index.ts +6 -3
  63. package/src/models/interfaces.ts +25 -32
  64. package/src/utils/__tests__/accountUtils.test.ts +142 -0
  65. package/src/utils/__tests__/consumeSsoReturn.test.ts +229 -37
  66. package/src/utils/accountUtils.ts +20 -5
  67. package/src/utils/ssoReturn.ts +98 -37
  68. package/dist/cjs/mixins/OxyServices.developer.js +0 -97
  69. package/dist/cjs/mixins/OxyServices.karma.js +0 -108
  70. package/dist/esm/mixins/OxyServices.developer.js +0 -94
  71. package/dist/esm/mixins/OxyServices.karma.js +0 -105
  72. package/dist/types/mixins/OxyServices.developer.d.ts +0 -106
  73. package/dist/types/mixins/OxyServices.karma.d.ts +0 -92
  74. package/src/mixins/OxyServices.karma.ts +0 -111
@@ -104,14 +104,60 @@ export declare class HttpService {
104
104
  * into a `Headers`-compatible object.
105
105
  */
106
106
  private static parseXHRHeaders;
107
+ /**
108
+ * Delimiter that separates the logical `method:url[:data]` portion of a
109
+ * cache key from its identity suffix. Always APPENDED, never used to parse
110
+ * a key apart, so the `method:url` prefix stays intact for
111
+ * `clearCacheByPrefix` sweeps and `clearCacheEntry` base-key matching.
112
+ * The `clearCacheEntry` callsites all pass fixed, dataless logical keys
113
+ * (`GET:/users/<id>`, `GET:/session/user/<sessionId>`,
114
+ * `GET:/fedcm/me/authorized-apps`), so this readable suffix can never be
115
+ * ambiguous with a serialized request body.
116
+ */
117
+ private static readonly CACHE_IDENTITY_DELIM;
118
+ /**
119
+ * Derive a stable, non-sensitive identity discriminator for cache scoping.
120
+ *
121
+ * The GET-response cache MUST be partitioned by caller identity: endpoints
122
+ * with optional auth (e.g. `GET /profiles/recommendations`) return different
123
+ * content for an anonymous vs an authenticated caller, and per-user content
124
+ * for different authenticated users. Keying solely on `method:url:data`
125
+ * (the previous behavior) let an anonymous response be served to an
126
+ * authenticated caller — surfacing as "Who to follow" recommending accounts
127
+ * the user already follows after a cold-boot session restore.
128
+ *
129
+ * We use the access token's decoded user id (`userId || id`) rather than the
130
+ * raw JWT so the token never lands in a cache key (no token leakage through
131
+ * any cache-key logging, no key bloat). The acting-as id is folded in because
132
+ * managed-account responses differ per acting identity — and `X-Acting-As`
133
+ * already changes the server response for the same bearer token. Falls back
134
+ * to `'anon'` when there is no token, and to a short FNV-1a hash of the token
135
+ * only if it is present but cannot be decoded (degraded but still partitioned,
136
+ * never colliding anon with authed).
137
+ */
138
+ private computeIdentityTag;
107
139
  /**
108
140
  * Generate cache key efficiently
109
141
  * Uses a content-addressed hash for large payloads so two requests with
110
142
  * the same shape but different values never collide on the same key
111
143
  * (which would silently serve stale data — e.g. paginated search results,
112
144
  * large object updates).
145
+ *
146
+ * The key is identity-scoped: the logical `method:url[:data]` portion is
147
+ * suffixed with ` id=<identityTag>` so two callers with different
148
+ * identities (anon vs authed, or two different users) never share an entry.
149
+ * The identity tag is placed at the END so the key still STARTS with
150
+ * `method:url`, preserving the prefix-based invalidation in
151
+ * `clearCacheByPrefix` (e.g. `GET:/session/user/`) and the base-key matching
152
+ * in `clearCacheEntry`.
113
153
  */
114
154
  private generateCacheKey;
155
+ /**
156
+ * Build the identity-agnostic portion of a cache key (`method:url[:data]`).
157
+ * Kept separate so identity scoping is applied in exactly one place
158
+ * (`generateCacheKey`) and cannot drift between the cache and dedupe paths.
159
+ */
160
+ private generateBaseCacheKey;
115
161
  /**
116
162
  * Build full URL with query params
117
163
  */
@@ -169,6 +215,17 @@ export declare class HttpService {
169
215
  hasAccessToken(): boolean;
170
216
  getBaseURL(): string;
171
217
  clearCache(): void;
218
+ /**
219
+ * Delete a cache entry by its LOGICAL key (`method:url[:data]`).
220
+ *
221
+ * Because the response cache is identity-scoped — stored keys carry an
222
+ * ` id=<identityTag>` suffix — a caller passing the logical key
223
+ * `GET:/users/<id>` must invalidate that resource for EVERY identity that
224
+ * cached it (e.g. `updateProfile` busting a user representation that may be
225
+ * cached under both the owner's id and a viewer's id). We therefore delete
226
+ * the exact key (for any pre-existing un-suffixed entries) AND every
227
+ * identity-scoped variant `<key> id=*`.
228
+ */
172
229
  clearCacheEntry(key: string): void;
173
230
  /**
174
231
  * Delete every cache entry whose key starts with `prefix`.
@@ -80,9 +80,10 @@ import { composeOxyServices } from './mixins';
80
80
  * - **Privacy**: Blocked and restricted users
81
81
  * - **Language**: Language detection and metadata
82
82
  * - **Payment**: Payment processing
83
- * - **Karma**: Karma system
83
+ * - **Reputation**: Reputation system (Oxy Trust)
84
84
  * - **Assets**: File upload and asset management
85
85
  * - **Applications**: Application, membership, and credential management
86
+ * - **Workspaces**: Workspace and membership management
86
87
  * - **Location**: Location-based features
87
88
  * - **Analytics**: Analytics tracking
88
89
  * - **Devices**: Device management
@@ -5,9 +5,9 @@
5
5
  export declare const packageInfo: {
6
6
  readonly name: "@oxyhq/services";
7
7
  readonly version: "5.2.1";
8
- readonly description: "Reusable OxyHQ module to handle authentication, user management, karma system and more 🚀";
8
+ readonly description: "Reusable OxyHQ module to handle authentication, user management, reputation system (Oxy Trust) and more 🚀";
9
9
  readonly main: "lib/commonjs/node/index.js";
10
10
  readonly module: "lib/module/node/index.js";
11
11
  readonly types: "lib/typescript/node/index.d.ts";
12
12
  };
13
- export declare const name: "@oxyhq/services", version: "5.2.1", description: "Reusable OxyHQ module to handle authentication, user management, karma system and more 🚀";
13
+ export declare const name: "@oxyhq/services", version: "5.2.1", description: "Reusable OxyHQ module to handle authentication, user management, reputation system (Oxy Trust) and more 🚀";
@@ -33,7 +33,9 @@ export type { ServiceApp, ServiceActingAsVerification } from './mixins/OxyServic
33
33
  export type { CreateManagedAccountInput, ManagedAccountManager, ManagedAccount, } from './mixins/OxyServices.managedAccounts';
34
34
  export type { ContactDiscoveryMatch, ContactDiscoveryResponse, } from './mixins/OxyServices.contacts';
35
35
  export { OxyAppDataIdentifierError } from './mixins/OxyServices.appData';
36
- export type { Application, ApplicationMember, ApplicationCredential, ApplicationRole, ApplicationType, ApplicationStatus, ApplicationMemberStatus, ApplicationCredentialType, ApplicationCredentialStatus, ApplicationEnvironment, CreateApplicationInput, UpdateApplicationInput, InviteApplicationMemberInput, UpdateApplicationMemberInput, TransferApplicationOwnershipInput, CreateApplicationCredentialInput, ApplicationCredentialWithSecret, RotateApplicationCredentialResult, ApplicationUsagePeriod, ApplicationUsageSummary, ApplicationUsageByDay, ApplicationUsageByEndpoint, ApplicationUsageStats, ApplicationSuccessResult, } from './mixins/OxyServices.applications';
36
+ export type { Application, PublicApplication, ApplicationMember, ApplicationCredential, ApplicationRole, ApplicationType, ApplicationStatus, ApplicationMemberStatus, ApplicationCredentialType, ApplicationCredentialStatus, ApplicationEnvironment, CreateApplicationInput, UpdateApplicationInput, InviteApplicationMemberInput, UpdateApplicationMemberInput, TransferApplicationOwnershipInput, CreateApplicationCredentialInput, ApplicationCredentialWithSecret, RotateApplicationCredentialResult, ApplicationUsagePeriod, ApplicationUsageSummary, ApplicationUsageByDay, ApplicationUsageByEndpoint, ApplicationUsageStats, ApplicationSuccessResult, } from './mixins/OxyServices.applications';
37
+ export type { Workspace, WorkspaceMember, WorkspaceRole, WorkspaceType, WorkspaceStatus, WorkspaceMemberStatus, CreateWorkspaceInput, UpdateWorkspaceInput, InviteWorkspaceMemberInput, UpdateWorkspaceMemberInput, TransferWorkspaceOwnershipInput, WorkspaceSuccessResult, } from './mixins/OxyServices.workspaces';
38
+ export type { ReputationCategory, TrustTier, ReputationTransactionStatus, ReputationTargetEntityType, ReputationDisputeStatus, ReputationInfluenceContext, ReputationTransaction, ReputationBalanceBreakdown, ReputationInfluence, ReputationReliability, ReputationBalance, ReputationDispute, ReputationRule, ReputationLeaderboardEntry, ReputationInfluenceResult, ReverseReputationTransactionResult, AwardReputationInput, CreateReputationDisputeInput, ResolveReputationDisputeInput, UpsertReputationRuleInput, ReverseReputationTransactionInput, } from './mixins/OxyServices.reputation';
37
39
  export { SessionSyncRequiredError, AuthenticationFailedError, ensureValidToken, isAuthenticationError, withAuthErrorHandling, authenticatedApiCall, } from './utils/authHelpers';
38
40
  export type { HandleApiErrorOptions } from './utils/authHelpers';
39
41
  export { mergeSessions, normalizeAndSortSessions, sessionsArraysEqual, } from './utils/sessionUtils';
@@ -47,7 +49,7 @@ export { RecoveryPhraseService } from './crypto/recoveryPhrase';
47
49
  export type { RecoveryPhraseResult } from './crypto/recoveryPhrase';
48
50
  export { DeviceManager } from './utils/deviceManager';
49
51
  export type { DeviceFingerprint, StoredDeviceInfo } from './utils/deviceManager';
50
- export type { OxyConfig, PrivacySettings, NotificationPreferences, UserPreferences, User, LoginResponse, Notification, Wallet, Transaction, BlockedUser, RestrictedUser, TransferFundsRequest, PurchaseRequest, WithdrawalRequest, TransactionResponse, PaginationInfo, SearchProfilesResponse, KarmaRule, KarmaHistory, KarmaLeaderboardEntry, KarmaAwardRequest, ApiError, PaymentMethod, PaymentRequest, PaymentResponse, AnalyticsData, FollowerDetails, ContentViewer, FileMetadata, FileUploadResponse, FileListResponse, FileUpdateRequest, FileDeleteResponse, RNFileDescriptor, AssetUploadInput, FileVisibility, AssetLink, AssetMetadata, AssetVariant, Asset, AssetInitRequest, AssetInitResponse, AssetCompleteRequest, AssetLinkRequest, AssetUnlinkRequest, AssetUrlResponse, AssetDeleteSummary, AssetUpdateVisibilityRequest, AssetUpdateVisibilityResponse, AccountStorageCategoryUsage, AccountStorageUsageResponse, SecurityEventType, SecurityEventSeverity, SecurityActivity, SecurityActivityResponse, AssetUploadProgress, DeviceSession, DeviceSessionsResponse, DeviceSessionLogoutResponse, UpdateDeviceNameResponse, } from './models/interfaces';
52
+ export type { OxyConfig, PrivacySettings, NotificationPreferences, UserPreferences, User, LoginResponse, Notification, Wallet, Transaction, BlockedUser, RestrictedUser, TransferFundsRequest, PurchaseRequest, WithdrawalRequest, TransactionResponse, PaginationInfo, SearchProfilesResponse, ApiError, PaymentMethod, PaymentRequest, PaymentResponse, AnalyticsData, FollowerDetails, ContentViewer, FileMetadata, FileUploadResponse, FileListResponse, FileUpdateRequest, FileDeleteResponse, RNFileDescriptor, AssetUploadInput, FileVisibility, AssetLink, AssetMetadata, AssetVariant, Asset, AssetInitRequest, AssetInitResponse, AssetCompleteRequest, AssetLinkRequest, AssetUnlinkRequest, AssetUrlResponse, AssetDeleteSummary, AssetUpdateVisibilityRequest, AssetUpdateVisibilityResponse, AccountStorageCategoryUsage, AccountStorageUsageResponse, SecurityEventType, SecurityEventSeverity, SecurityActivity, SecurityActivityResponse, AssetUploadProgress, DeviceSession, DeviceSessionsResponse, DeviceSessionLogoutResponse, UpdateDeviceNameResponse, } from './models/interfaces';
51
53
  export { SECURITY_EVENT_SEVERITY_MAP } from './models/interfaces';
52
54
  export { TopicType, TopicSource } from './models/Topic';
53
55
  export type { TopicData, TopicTranslation } from './models/Topic';
@@ -49,12 +49,22 @@ export interface Application {
49
49
  webhookUrl?: string;
50
50
  devWebhookUrl?: string;
51
51
  createdByUserId: string;
52
+ /**
53
+ * The workspace this application belongs to (workspace `_id`), or `null` for
54
+ * applications not owned by a workspace. Used by the console to scope apps to
55
+ * a workspace and to branch on workspace-derived access.
56
+ */
57
+ workspaceId: string | null;
52
58
  createdAt: string;
53
59
  updatedAt: string;
54
60
  /**
55
61
  * The calling user's own membership in this application, embedded by the API
56
62
  * on list (`GET /applications`) and detail (`GET /applications/:appId`)
57
63
  * responses. Use `callerMembership.permissions` to gate UI affordances.
64
+ *
65
+ * When the caller's access is derived from a workspace membership rather than
66
+ * a direct application membership, the API returns a synthetic membership
67
+ * with `source: 'workspace'` and `_id: null`.
58
68
  */
59
69
  callerMembership?: ApplicationMember;
60
70
  }
@@ -63,7 +73,11 @@ export interface Application {
63
73
  * on the server at write time.
64
74
  */
65
75
  export interface ApplicationMember {
66
- _id: string;
76
+ /**
77
+ * The membership's Mongo `_id`. `null` for a synthetic, workspace-derived
78
+ * membership (see {@link Application.callerMembership} and `source`).
79
+ */
80
+ _id: string | null;
67
81
  applicationId: string;
68
82
  userId: string;
69
83
  role: ApplicationRole;
@@ -71,6 +85,13 @@ export interface ApplicationMember {
71
85
  invitedByUserId?: string;
72
86
  joinedAt?: string;
73
87
  status: ApplicationMemberStatus;
88
+ /**
89
+ * Origin of this membership. When `'workspace'`, the membership is synthetic
90
+ * and derived from the caller's workspace membership rather than a direct
91
+ * application membership (in which case `_id` is `null`). Absent or any other
92
+ * value indicates a direct application membership.
93
+ */
94
+ source?: 'workspace';
74
95
  createdAt: string;
75
96
  updatedAt: string;
76
97
  }
@@ -98,6 +119,38 @@ export interface ApplicationCredential {
98
119
  createdAt: string;
99
120
  updatedAt: string;
100
121
  }
122
+ /**
123
+ * Sanitized, PUBLIC application identity returned by the API when resolving a
124
+ * cross-app/OAuth client to a registered {@link Application}.
125
+ *
126
+ * Unlike {@link Application}, this shape carries NO sensitive or membership
127
+ * fields — it is safe to display unauthenticated in consent/authorize screens
128
+ * and device-flow approval UIs. The API resolves a `client_id` (OAuth
129
+ * credential public key) to the owning application and projects only the
130
+ * fields below. `id` is the application's `_id` as a string.
131
+ */
132
+ export interface PublicApplication {
133
+ /** The application's Mongo `_id` as a string. */
134
+ id: string;
135
+ /** Human-readable application name shown to the user. */
136
+ name: string;
137
+ /** Optional short description of what the application does. */
138
+ description?: string;
139
+ /** Optional icon URL for the application. */
140
+ icon?: string;
141
+ /** Optional public website/homepage URL for the application. */
142
+ websiteUrl?: string;
143
+ /** Application classification (set by Oxy platform staff). */
144
+ type: ApplicationType;
145
+ /** Whether the application is an officially endorsed Oxy application. */
146
+ isOfficial: boolean;
147
+ /** Whether the application is an internal Oxy ecosystem application. */
148
+ isInternal: boolean;
149
+ /** OAuth scopes the application is configured to request. */
150
+ scopes: string[];
151
+ /** Optional display name of the developer/owner organisation. */
152
+ developerName?: string;
153
+ }
101
154
  /** Input accepted by `createApplication`. Staff-only fields are not settable here. */
102
155
  export interface CreateApplicationInput {
103
156
  name: string;
@@ -106,6 +159,11 @@ export interface CreateApplicationInput {
106
159
  icon?: string;
107
160
  redirectUris?: string[];
108
161
  scopes?: string[];
162
+ /**
163
+ * Optional workspace `_id` to create the app in. Omitted → API defaults to
164
+ * the caller's personal workspace.
165
+ */
166
+ workspaceId?: string;
109
167
  }
110
168
  /** Input accepted by `updateApplication`. Staff-only fields are not settable here. */
111
169
  export interface UpdateApplicationInput {
@@ -121,7 +179,11 @@ export interface UpdateApplicationInput {
121
179
  }
122
180
  /** Input accepted by `inviteApplicationMember`. The owner role cannot be invited. */
123
181
  export interface InviteApplicationMemberInput {
124
- userId: string;
182
+ /**
183
+ * The username or email of the user to invite. Resolved to a user server-side;
184
+ * an unknown value yields a 404 "User not found".
185
+ */
186
+ usernameOrEmail: string;
125
187
  role: Exclude<ApplicationRole, 'owner'>;
126
188
  }
127
189
  /** Input accepted by `updateApplicationMember`. */
@@ -192,10 +254,27 @@ export interface ApplicationSuccessResult {
192
254
  }
193
255
  export declare function OxyServicesApplicationsMixin<T extends typeof OxyServicesBase>(Base: T): {
194
256
  new (...args: any[]): {
257
+ /**
258
+ * Resolve an OAuth client identifier to the owning application's PUBLIC
259
+ * identity. No authentication required — the API returns only sanitized,
260
+ * display-safe metadata ({@link PublicApplication}). Use this to render the
261
+ * requesting application's name/icon in consent, authorize, and device-flow
262
+ * approval UIs before any session exists.
263
+ *
264
+ * @param clientId - The OAuth `client_id` (an active credential's public
265
+ * key). URL-encoded before being placed in the path.
266
+ */
267
+ getPublicApplication(clientId: string): Promise<PublicApplication>;
195
268
  /**
196
269
  * List applications the current user is an active member of.
270
+ *
271
+ * @param workspaceId - Optional workspace `_id` to scope the listing to
272
+ * applications belonging to that workspace. When provided it is appended
273
+ * as a `workspaceId` query parameter (URL-encoded). The query string is
274
+ * part of the request path, so the response cache keys on it
275
+ * automatically — scoped and unscoped lists never collide.
197
276
  */
198
- getApplications(): Promise<Application[]>;
277
+ getApplications(workspaceId?: string): Promise<Application[]>;
199
278
  /**
200
279
  * Create a new application. The caller becomes its `owner`.
201
280
  * @param data - Application configuration. Staff-only fields are ignored.
@@ -225,7 +304,9 @@ export declare function OxyServicesApplicationsMixin<T extends typeof OxyService
225
304
  /**
226
305
  * Add a member to an application.
227
306
  * @param applicationId - The application's Mongo `_id`.
228
- * @param data - Target user id and role (never `owner`).
307
+ * @param data - Target user's username or email and role (never `owner`).
308
+ * The server resolves `usernameOrEmail` to a user; an unknown value yields
309
+ * a 404 "User not found".
229
310
  */
230
311
  inviteApplicationMember(applicationId: string, data: InviteApplicationMemberInput): Promise<ApplicationMember>;
231
312
  /**
@@ -329,12 +410,7 @@ export declare function OxyServicesApplicationsMixin<T extends typeof OxyService
329
410
  healthCheck(): Promise<{
330
411
  status: string;
331
412
  users?: number;
332
- timestamp? /**
333
- * Create a credential. The plaintext `secret` is returned exactly ONCE;
334
- * the server stores only a hash and will never return it again.
335
- * @param applicationId - The application's Mongo `_id`.
336
- * @param data - Credential configuration.
337
- */: string;
413
+ timestamp?: string;
338
414
  [key: string]: any;
339
415
  }>;
340
416
  };
@@ -65,7 +65,6 @@ export interface UserStats {
65
65
  commentCount: number;
66
66
  followerCount: number;
67
67
  followingCount: number;
68
- karmaScore?: number;
69
68
  }
70
69
  export interface HistoryItem {
71
70
  id: string;