@vibexnpm/talkx 5.4.0 → 5.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibexnpm/talkx",
3
- "version": "5.4.0",
3
+ "version": "5.6.0",
4
4
  "type": "module",
5
5
  "description": "TalkFlow SDK - Chat & WebRTC unified client",
6
6
  "main": "dist/talkflow-sdk.umd.js",
@@ -237,10 +237,134 @@ class TalkFlowClient extends EventEmitter {
237
237
 
238
238
  // ==================== 사용자 API ====================
239
239
 
240
+ /**
241
+ * 회원 로그인 — 이메일/비밀번호로 채팅 접속 일체를 받는다. **클라이언트 생성 전에 호출한다.**
242
+ *
243
+ * <p>{@link #registerUser} 와 달리 Server Key 도 고객사 BFF 도 필요 없다. 응답의
244
+ * {@code clientKey}/{@code projectId}/{@code accessToken} 이 그대로 SDK 초기화 입력이다.</p>
245
+ *
246
+ * <p><b>회사 선택 단계가 없다</b>: 로그인 키가 전역 유일이라 이메일 하나로 회원과 회사가
247
+ * 함께 정해진다. 퇴사하면 그 키가 풀려 다른 회사에서 같은 이메일을 다시 쓸 수 있다.</p>
248
+ *
249
+ * @param {Object} options
250
+ * @param {string} options.serverUrl - 채팅 서버 base URL
251
+ * @param {string} options.email
252
+ * @param {string} options.password
253
+ * @returns {Promise<Object>} `{accessToken, tokenType, expiresIn, projectId, clientKey, user}`
254
+ *
255
+ * @example
256
+ * const login = await TalkFlowClient.loginUser({
257
+ * serverUrl: 'https://chat.apiorbit.net',
258
+ * email: 'dan@example.com',
259
+ * password: '********'
260
+ * });
261
+ *
262
+ * const client = new TalkFlowClient({
263
+ * apiKey: login.clientKey,
264
+ * projectId: login.projectId,
265
+ * jwtToken: login.accessToken
266
+ * });
267
+ * await client.connect();
268
+ */
269
+ static async loginUser({ serverUrl, email, password }) {
270
+ if (!serverUrl) throw new Error('serverUrl is required');
271
+ if (!email) throw new Error('email is required');
272
+ if (!password) throw new Error('password is required');
273
+
274
+ // 로그인은 키를 «받기 위해» 부르는 경로라 X-API-KEY/X-PROJECT-ID 가 없다(서버에서 필터 제외).
275
+ const client = new ApiClient({ baseUrl: serverUrl, apiKey: '', projectId: '' });
276
+ const response = await client.post('/api/v1/auth/login', { email, password });
277
+ return (response && response.data) ? response.data : response;
278
+ }
279
+
280
+ /**
281
+ * 회원 로그인 (인스턴스) — 성공 시 JWT 를 자동 설정한다.
282
+ *
283
+ * <p>이미 클라이언트가 있는 상태의 재로그인·계정 전환용이다. 최초 진입은 클라이언트 생성 전에
284
+ * 부르는 정적 {@link TalkFlowClient.loginUser} 를 쓴다 — 그쪽이 {@code clientKey} 까지 준다.</p>
285
+ *
286
+ * @param {Object} credentials
287
+ * @param {string} credentials.email
288
+ * @param {string} credentials.password
289
+ * @returns {Promise<Object>} 로그인 응답
290
+ */
291
+ async loginUser({ email, password }) {
292
+ const response = await this.apiClient.post('/api/v1/auth/login', { email, password });
293
+ const data = (response && response.data) ? response.data : response;
294
+
295
+ if (data && data.accessToken) {
296
+ await this.setToken(data.accessToken);
297
+ this.logger.info('Member logged in, token auto-set');
298
+ }
299
+ return data;
300
+ }
301
+
302
+ /**
303
+ * 내 정보 조회.
304
+ *
305
+ * @returns {Promise<Object>} `{userId, email, name, phone, profileUrl, companyRole, orgNodeId, orgName, ...}`
306
+ */
307
+ async getMyProfile() {
308
+ this._checkToken();
309
+ const response = await this.apiClient.get('/api/v1/me');
310
+ return (response && response.data) ? response.data : response;
311
+ }
312
+
313
+ /**
314
+ * 내 정보 수정 — 이름·전화번호·프로필 이미지.
315
+ *
316
+ * <p>서버가 <b>새 JWT</b> 를 함께 준다: {@code name}/{@code profileUrl} 이 토큰 claim 이라
317
+ * 갱신하지 않으면 옛 값이 토큰 만료(7일)까지 계속 나간다. 여기서 자동 채택한다.</p>
318
+ *
319
+ * <p>이메일·조직·역할은 바꿀 수 없다 — 이메일은 로그인 키, 조직은 파트너가 정하고,
320
+ * 역할은 본인이 승급할 수 없어야 한다.</p>
321
+ *
322
+ * @param {Object} profile
323
+ * @param {string} [profile.name]
324
+ * @param {string} [profile.phone]
325
+ * @param {string} [profile.profileUrl]
326
+ * @returns {Promise<Object>} 갱신된 내 정보 (accessToken 포함)
327
+ */
328
+ async updateMyProfile(profile) {
329
+ this._checkToken();
330
+ const response = await this.apiClient.put('/api/v1/me', profile);
331
+ const data = (response && response.data) ? response.data : response;
332
+
333
+ if (data && data.accessToken) {
334
+ // 토큰 교체 실패로 수정 자체를 실패시키지 않는다 — 서버 반영은 이미 끝났고 옛 토큰도
335
+ // 유효(낡았을 뿐)하므로 여기서 throw 하면 호출자가 이미 적용된 수정을 다시 시도한다.
336
+ try {
337
+ await this.setToken(data.accessToken);
338
+ } catch (error) {
339
+ this.logger.warn('Profile updated but token refresh failed; keeping the old token', error);
340
+ }
341
+ }
342
+ return data;
343
+ }
344
+
345
+ /**
346
+ * 비밀번호 변경 — 현재 비밀번호를 재확인한다.
347
+ *
348
+ * <p>토큰만 탈취해도 비밀번호를 바꿀 수 있으면 계정을 통째로 빼앗긴다. 비밀번호는 바뀌어도
349
+ * 토큰은 그대로 유효하다 — 재로그인이 필요하지 않다.</p>
350
+ *
351
+ * @param {Object} params
352
+ * @param {string} params.currentPassword
353
+ * @param {string} params.newPassword - 8자 이상
354
+ */
355
+ async changeMyPassword({ currentPassword, newPassword }) {
356
+ this._checkToken();
357
+ return this.apiClient.put('/api/v1/me/password', { currentPassword, newPassword });
358
+ }
359
+
240
360
  /**
241
361
  * 사용자 인증 (등록/로그인).
242
362
  * 인증 성공 시 반환된 JWT 토큰을 자동으로 설정합니다.
243
363
  *
364
+ * <h3>⚠️ DEPRECATED — {@link TalkFlowClient.loginUser} 로 대체</h3>
365
+ * <p>고객사 앱이 자기 회원 ID 를 들고 오던 경로다. 서버에서 {@code POST /api/v1/users/auth} 가
366
+ * 제거될 예정이며 그때 이 메서드도 함께 사라진다. 신규 코드는 {@code loginUser} 를 쓴다.</p>
367
+ *
244
368
  * <h3>⚠️ Server API Key 전용</h3>
245
369
  * <p>이 메서드는 JWT 를 발급하는 엔드포인트 ({@code POST /api/v1/users/auth}) 를 호출합니다.
246
370
  * <strong>프로덕션 환경에서는 Client API Key 로 이 메서드를 호출하면 서버가 403 을 반환합니다.</strong></p>
package/types/index.d.ts CHANGED
@@ -962,6 +962,48 @@ export interface DecisionResponse {
962
962
  optionId: string;
963
963
  }
964
964
 
965
+ /** 로그인한 회원. `userId` 는 메시지 발신자 식별과 같은 값이다. */
966
+ export interface LoginMember {
967
+ userId: string;
968
+ email?: string | null;
969
+ nickname?: string | null;
970
+ profileUrl?: string | null;
971
+ preferredLanguage?: string | null;
972
+ }
973
+
974
+ /**
975
+ * `TalkFlowClient.loginUser` 응답.
976
+ *
977
+ * 회사 선택 단계가 없다 — 로그인 키가 전역 유일이라 이메일 하나로 회원과 회사가 함께 정해진다.
978
+ */
979
+ export interface LoginResult {
980
+ accessToken: string;
981
+ tokenType: string;
982
+ expiresIn?: number;
983
+ projectId: string;
984
+ /** 회사의 활성 ck- 키. SDK 초기화의 `apiKey` 로 그대로 넣는다. */
985
+ clientKey: string;
986
+ user: LoginMember;
987
+ }
988
+
989
+ /** 내 정보. 수정 응답에는 `accessToken` 이 함께 온다(name/profileUrl 이 토큰 claim). */
990
+ export interface MyProfile {
991
+ userId: string;
992
+ email?: string | null;
993
+ name?: string | null;
994
+ phone?: string | null;
995
+ profileUrl?: string | null;
996
+ /** 회사 역할 — 방 역할(ParticipantResponse.role)과 다른 축이다. */
997
+ companyRole: 'PARTNER' | 'MEMBER';
998
+ orgNodeId?: string | null;
999
+ orgName?: string | null;
1000
+ preferredLanguage?: string | null;
1001
+ projectId: string;
1002
+ joinedAt?: string | null;
1003
+ accessToken?: string;
1004
+ expiresIn?: number;
1005
+ }
1006
+
965
1007
  /** 채팅방 참가자. */
966
1008
  export interface ParticipantResponse {
967
1009
  userId: string;
@@ -2251,6 +2293,30 @@ export default class TalkFlowClient implements SdkEventEmitter<TalkFlowClientEve
2251
2293
  removeAllListeners(event?: keyof TalkFlowClientEvents): void;
2252
2294
  listenerCount(event: keyof TalkFlowClientEvents): number;
2253
2295
 
2296
+ // 회원 인증 · 내 정보
2297
+ /**
2298
+ * 회원 로그인 — 클라이언트 생성 **전에** 호출한다. Server Key 도 고객사 BFF 도 필요 없다.
2299
+ * 응답의 `clientKey`/`projectId`/`accessToken` 이 그대로 SDK 초기화 입력이다.
2300
+ * 회사 선택 단계가 없다 — 로그인 키가 전역 유일이다.
2301
+ */
2302
+ static loginUser(options: {
2303
+ serverUrl: string;
2304
+ email: string;
2305
+ password: string;
2306
+ }): Promise<LoginResult>;
2307
+
2308
+ /** 회원 로그인 (인스턴스) — 재로그인·계정 전환용. 성공 시 토큰을 자동 설정한다. */
2309
+ loginUser(credentials: { email: string; password: string }): Promise<LoginResult>;
2310
+
2311
+ /** 내 정보 조회. */
2312
+ getMyProfile(): Promise<MyProfile>;
2313
+
2314
+ /** 내 정보 수정 — 응답의 새 토큰을 자동 채택한다(name/profileUrl 이 토큰 claim). */
2315
+ updateMyProfile(profile: { name?: string; phone?: string; profileUrl?: string }): Promise<MyProfile>;
2316
+
2317
+ /** 비밀번호 변경 — 현재 비밀번호 재확인. 토큰은 그대로 유효해 재로그인이 필요 없다. */
2318
+ changeMyPassword(params: { currentPassword: string; newPassword: string }): Promise<unknown>;
2319
+
2254
2320
  // Connection lifecycle
2255
2321
  connect(jwt?: string, options?: ConnectOptions): Promise<void>;
2256
2322
  disconnect(): Promise<void>;