mailisk 2.3.0 → 2.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.
package/README.md CHANGED
@@ -242,8 +242,8 @@ Create a saved TOTP device from a Base32 shared secret using default settings: 6
242
242
  ```js
243
243
  const device = await mailisk.createTotpDevice({
244
244
  name: "GitHub staging",
245
- sharedSecret: "JBSWY3DPEHPK3PXP",
246
- expiresAt: "2026-06-01T12:00:00.000Z",
245
+ shared_secret: "JBSWY3DPEHPK3PXP",
246
+ expires_at: "2026-06-01T12:00:00.000Z",
247
247
  });
248
248
  ```
249
249
 
@@ -269,7 +269,7 @@ Create a saved TOTP device from a Base32 secret key.
269
269
 
270
270
  ```js
271
271
  const device = await mailisk.createTotpDeviceFromBase32SecretKey({
272
- base32SecretKey: "JBSWY3DPEHPK3PXP",
272
+ base32_secret_key: "JBSWY3DPEHPK3PXP",
273
273
  username: "qa@example.com",
274
274
  issuer: "GitHub",
275
275
  });
@@ -281,27 +281,33 @@ Create a saved TOTP device from an `otpauth://totp/...` URL.
281
281
 
282
282
  ```js
283
283
  const device = await mailisk.createTotpDeviceFromOtpAuthUrl({
284
- otpAuthUrl: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
284
+ otp_auth_url: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
285
285
  });
286
286
  ```
287
287
 
288
- ### `getTotpOtpBySharedSecret(sharedSecret)`
288
+ ### `getTotpOtpBySharedSecret(sharedSecret, params?)`
289
289
 
290
290
  Generate a TOTP code from a shared secret without saving a device.
291
+ Pass `min_seconds_until_expire` to wait for the next TOTP period when the current code has fewer seconds left.
291
292
 
292
293
  ```js
293
- const otp = await mailisk.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP");
294
+ const otp = await mailisk.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP", {
295
+ min_seconds_until_expire: 10,
296
+ });
294
297
 
295
298
  console.log(otp.code);
296
299
  console.log(otp.expires);
297
300
  ```
298
301
 
299
- ### `getTotpOtpByDeviceId(deviceId)`
302
+ ### `getTotpOtpByDeviceId(deviceId, params?)`
300
303
 
301
304
  Generate a TOTP code for a saved device.
305
+ Pass `min_seconds_until_expire` to wait for the next TOTP period when the current code has fewer seconds left.
302
306
 
303
307
  ```js
304
- const otp = await mailisk.getTotpOtpByDeviceId(device.id);
308
+ const otp = await mailisk.getTotpOtpByDeviceId(device.id, {
309
+ min_seconds_until_expire: 10,
310
+ });
305
311
  ```
306
312
 
307
313
  ### `deleteTotpDevice(deviceId)`
package/dist/index.d.mts CHANGED
@@ -244,7 +244,7 @@ interface TotpDevice {
244
244
  period: number;
245
245
  algorithm: TotpAlgorithm;
246
246
  source: TotpDeviceSource;
247
- expiresAt?: string | null;
247
+ expires_at?: string | null;
248
248
  created_at: string;
249
249
  updated_at: string;
250
250
  }
@@ -265,11 +265,11 @@ interface ListTotpDevicesResponse {
265
265
  }
266
266
  interface CreateTotpDeviceParams {
267
267
  /** Base32 shared secret. Uses default TOTP settings. */
268
- sharedSecret: string;
268
+ shared_secret: string;
269
269
  /** Optional saved-device display name. Max 120 characters. */
270
270
  name?: string;
271
271
  /** Future ISO timestamp after which the saved device expires. */
272
- expiresAt?: string;
272
+ expires_at?: string;
273
273
  }
274
274
  interface CreateCustomTotpDeviceParams {
275
275
  /** Base32 shared secret. */
@@ -287,11 +287,11 @@ interface CreateCustomTotpDeviceParams {
287
287
  /** Hashing algorithm. */
288
288
  algorithm?: TotpAlgorithm;
289
289
  /** Future ISO timestamp after which the saved device expires. */
290
- expiresAt?: string;
290
+ expires_at?: string;
291
291
  }
292
292
  interface CreateBase32SecretKeyTotpDeviceParams {
293
293
  /** Base32 shared secret key. */
294
- base32SecretKey: string;
294
+ base32_secret_key: string;
295
295
  /** Optional saved-device display name. Max 120 characters. */
296
296
  name?: string;
297
297
  /** Account label. Max 240 characters. */
@@ -305,11 +305,11 @@ interface CreateBase32SecretKeyTotpDeviceParams {
305
305
  /** Hashing algorithm. */
306
306
  algorithm?: TotpAlgorithm;
307
307
  /** Future ISO timestamp after which the saved device expires. */
308
- expiresAt?: string;
308
+ expires_at?: string;
309
309
  }
310
310
  interface CreateOtpAuthUrlTotpDeviceParams {
311
311
  /** otpauth://totp URL with a secret query parameter. */
312
- otpAuthUrl: string;
312
+ otp_auth_url: string;
313
313
  /** Optional saved-device display name. Max 120 characters. */
314
314
  name?: string;
315
315
  /** Account label, used when missing from the URL label. Max 240 characters. */
@@ -323,7 +323,11 @@ interface CreateOtpAuthUrlTotpDeviceParams {
323
323
  /** Hashing algorithm, used when missing from the URL. */
324
324
  algorithm?: TotpAlgorithm;
325
325
  /** Future ISO timestamp after which the saved device expires. */
326
- expiresAt?: string;
326
+ expires_at?: string;
327
+ }
328
+ interface GetTotpOtpParams {
329
+ /** Minimum number of seconds the returned OTP should remain valid. Must be >= 0 and less than the TOTP period. */
330
+ min_seconds_until_expire?: number;
327
331
  }
328
332
  interface TotpOtpResponse {
329
333
  code: string;
@@ -379,7 +383,7 @@ declare class MailiskClient {
379
383
  * ```typescript
380
384
  * const device = await client.createTotpDevice({
381
385
  * name: "GitHub staging",
382
- * sharedSecret: "JBSWY3DPEHPK3PXP",
386
+ * shared_secret: "JBSWY3DPEHPK3PXP",
383
387
  * });
384
388
  * ```
385
389
  */
@@ -409,7 +413,7 @@ declare class MailiskClient {
409
413
  * Create a saved TOTP device from a Base32 secret key
410
414
  * ```typescript
411
415
  * const device = await client.createTotpDeviceFromBase32SecretKey({
412
- * base32SecretKey: "JBSWY3DPEHPK3PXP",
416
+ * base32_secret_key: "JBSWY3DPEHPK3PXP",
413
417
  * username: "qa@example.com",
414
418
  * issuer: "GitHub",
415
419
  * });
@@ -423,7 +427,7 @@ declare class MailiskClient {
423
427
  * Create a saved TOTP device from an otpauth URL
424
428
  * ```typescript
425
429
  * const device = await client.createTotpDeviceFromOtpAuthUrl({
426
- * otpAuthUrl: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
430
+ * otp_auth_url: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
427
431
  * });
428
432
  * ```
429
433
  */
@@ -434,20 +438,24 @@ declare class MailiskClient {
434
438
  * @example
435
439
  * Generate a TOTP code from a shared secret
436
440
  * ```typescript
437
- * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP");
441
+ * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP", {
442
+ * min_seconds_until_expire: 10,
443
+ * });
438
444
  * ```
439
445
  */
440
- getTotpOtpBySharedSecret(sharedSecret: string): Promise<TotpOtpResponse>;
446
+ getTotpOtpBySharedSecret(sharedSecret: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse>;
441
447
  /**
442
448
  * Generate a TOTP code for a saved device.
443
449
  *
444
450
  * @example
445
451
  * Generate a TOTP code for a saved device
446
452
  * ```typescript
447
- * const { code } = await client.getTotpOtpByDeviceId(device.id);
453
+ * const { code } = await client.getTotpOtpByDeviceId(device.id, {
454
+ * min_seconds_until_expire: 10,
455
+ * });
448
456
  * ```
449
457
  */
450
- getTotpOtpByDeviceId(deviceId: string): Promise<TotpOtpResponse>;
458
+ getTotpOtpByDeviceId(deviceId: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse>;
451
459
  /**
452
460
  * Delete a saved TOTP device.
453
461
  *
@@ -533,4 +541,4 @@ declare class MailiskClient {
533
541
  downloadAttachment(attachmentId: string): Promise<Buffer>;
534
542
  }
535
543
 
536
- export { type CreateBase32SecretKeyTotpDeviceParams, type CreateCustomTotpDeviceParams, type CreateOtpAuthUrlTotpDeviceParams, type CreateTotpDeviceParams, type Email, type EmailAddress, type EmailAttachment, type GetAttachmentResponse, type KnownTotpDeviceSource, type ListNamespacesResponse, type ListSmsNumbersResponse, type ListTotpDevicesParams, type ListTotpDevicesResponse, MailiskClient, type SearchInboxParams, type SearchInboxResponse, type SearchSmsMessagesParams, type SearchSmsMessagesResponse, type SendVirtualEmailParams, type SendVirtualSmsParams, type SmsMessage, type SmsNumber, type SmtpSettings, type TotpAlgorithm, type TotpDevice, type TotpDeviceSource, type TotpOtpResponse };
544
+ export { type CreateBase32SecretKeyTotpDeviceParams, type CreateCustomTotpDeviceParams, type CreateOtpAuthUrlTotpDeviceParams, type CreateTotpDeviceParams, type Email, type EmailAddress, type EmailAttachment, type GetAttachmentResponse, type GetTotpOtpParams, type KnownTotpDeviceSource, type ListNamespacesResponse, type ListSmsNumbersResponse, type ListTotpDevicesParams, type ListTotpDevicesResponse, MailiskClient, type SearchInboxParams, type SearchInboxResponse, type SearchSmsMessagesParams, type SearchSmsMessagesResponse, type SendVirtualEmailParams, type SendVirtualSmsParams, type SmsMessage, type SmsNumber, type SmtpSettings, type TotpAlgorithm, type TotpDevice, type TotpDeviceSource, type TotpOtpResponse };
package/dist/index.d.ts CHANGED
@@ -244,7 +244,7 @@ interface TotpDevice {
244
244
  period: number;
245
245
  algorithm: TotpAlgorithm;
246
246
  source: TotpDeviceSource;
247
- expiresAt?: string | null;
247
+ expires_at?: string | null;
248
248
  created_at: string;
249
249
  updated_at: string;
250
250
  }
@@ -265,11 +265,11 @@ interface ListTotpDevicesResponse {
265
265
  }
266
266
  interface CreateTotpDeviceParams {
267
267
  /** Base32 shared secret. Uses default TOTP settings. */
268
- sharedSecret: string;
268
+ shared_secret: string;
269
269
  /** Optional saved-device display name. Max 120 characters. */
270
270
  name?: string;
271
271
  /** Future ISO timestamp after which the saved device expires. */
272
- expiresAt?: string;
272
+ expires_at?: string;
273
273
  }
274
274
  interface CreateCustomTotpDeviceParams {
275
275
  /** Base32 shared secret. */
@@ -287,11 +287,11 @@ interface CreateCustomTotpDeviceParams {
287
287
  /** Hashing algorithm. */
288
288
  algorithm?: TotpAlgorithm;
289
289
  /** Future ISO timestamp after which the saved device expires. */
290
- expiresAt?: string;
290
+ expires_at?: string;
291
291
  }
292
292
  interface CreateBase32SecretKeyTotpDeviceParams {
293
293
  /** Base32 shared secret key. */
294
- base32SecretKey: string;
294
+ base32_secret_key: string;
295
295
  /** Optional saved-device display name. Max 120 characters. */
296
296
  name?: string;
297
297
  /** Account label. Max 240 characters. */
@@ -305,11 +305,11 @@ interface CreateBase32SecretKeyTotpDeviceParams {
305
305
  /** Hashing algorithm. */
306
306
  algorithm?: TotpAlgorithm;
307
307
  /** Future ISO timestamp after which the saved device expires. */
308
- expiresAt?: string;
308
+ expires_at?: string;
309
309
  }
310
310
  interface CreateOtpAuthUrlTotpDeviceParams {
311
311
  /** otpauth://totp URL with a secret query parameter. */
312
- otpAuthUrl: string;
312
+ otp_auth_url: string;
313
313
  /** Optional saved-device display name. Max 120 characters. */
314
314
  name?: string;
315
315
  /** Account label, used when missing from the URL label. Max 240 characters. */
@@ -323,7 +323,11 @@ interface CreateOtpAuthUrlTotpDeviceParams {
323
323
  /** Hashing algorithm, used when missing from the URL. */
324
324
  algorithm?: TotpAlgorithm;
325
325
  /** Future ISO timestamp after which the saved device expires. */
326
- expiresAt?: string;
326
+ expires_at?: string;
327
+ }
328
+ interface GetTotpOtpParams {
329
+ /** Minimum number of seconds the returned OTP should remain valid. Must be >= 0 and less than the TOTP period. */
330
+ min_seconds_until_expire?: number;
327
331
  }
328
332
  interface TotpOtpResponse {
329
333
  code: string;
@@ -379,7 +383,7 @@ declare class MailiskClient {
379
383
  * ```typescript
380
384
  * const device = await client.createTotpDevice({
381
385
  * name: "GitHub staging",
382
- * sharedSecret: "JBSWY3DPEHPK3PXP",
386
+ * shared_secret: "JBSWY3DPEHPK3PXP",
383
387
  * });
384
388
  * ```
385
389
  */
@@ -409,7 +413,7 @@ declare class MailiskClient {
409
413
  * Create a saved TOTP device from a Base32 secret key
410
414
  * ```typescript
411
415
  * const device = await client.createTotpDeviceFromBase32SecretKey({
412
- * base32SecretKey: "JBSWY3DPEHPK3PXP",
416
+ * base32_secret_key: "JBSWY3DPEHPK3PXP",
413
417
  * username: "qa@example.com",
414
418
  * issuer: "GitHub",
415
419
  * });
@@ -423,7 +427,7 @@ declare class MailiskClient {
423
427
  * Create a saved TOTP device from an otpauth URL
424
428
  * ```typescript
425
429
  * const device = await client.createTotpDeviceFromOtpAuthUrl({
426
- * otpAuthUrl: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
430
+ * otp_auth_url: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
427
431
  * });
428
432
  * ```
429
433
  */
@@ -434,20 +438,24 @@ declare class MailiskClient {
434
438
  * @example
435
439
  * Generate a TOTP code from a shared secret
436
440
  * ```typescript
437
- * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP");
441
+ * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP", {
442
+ * min_seconds_until_expire: 10,
443
+ * });
438
444
  * ```
439
445
  */
440
- getTotpOtpBySharedSecret(sharedSecret: string): Promise<TotpOtpResponse>;
446
+ getTotpOtpBySharedSecret(sharedSecret: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse>;
441
447
  /**
442
448
  * Generate a TOTP code for a saved device.
443
449
  *
444
450
  * @example
445
451
  * Generate a TOTP code for a saved device
446
452
  * ```typescript
447
- * const { code } = await client.getTotpOtpByDeviceId(device.id);
453
+ * const { code } = await client.getTotpOtpByDeviceId(device.id, {
454
+ * min_seconds_until_expire: 10,
455
+ * });
448
456
  * ```
449
457
  */
450
- getTotpOtpByDeviceId(deviceId: string): Promise<TotpOtpResponse>;
458
+ getTotpOtpByDeviceId(deviceId: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse>;
451
459
  /**
452
460
  * Delete a saved TOTP device.
453
461
  *
@@ -533,4 +541,4 @@ declare class MailiskClient {
533
541
  downloadAttachment(attachmentId: string): Promise<Buffer>;
534
542
  }
535
543
 
536
- export { type CreateBase32SecretKeyTotpDeviceParams, type CreateCustomTotpDeviceParams, type CreateOtpAuthUrlTotpDeviceParams, type CreateTotpDeviceParams, type Email, type EmailAddress, type EmailAttachment, type GetAttachmentResponse, type KnownTotpDeviceSource, type ListNamespacesResponse, type ListSmsNumbersResponse, type ListTotpDevicesParams, type ListTotpDevicesResponse, MailiskClient, type SearchInboxParams, type SearchInboxResponse, type SearchSmsMessagesParams, type SearchSmsMessagesResponse, type SendVirtualEmailParams, type SendVirtualSmsParams, type SmsMessage, type SmsNumber, type SmtpSettings, type TotpAlgorithm, type TotpDevice, type TotpDeviceSource, type TotpOtpResponse };
544
+ export { type CreateBase32SecretKeyTotpDeviceParams, type CreateCustomTotpDeviceParams, type CreateOtpAuthUrlTotpDeviceParams, type CreateTotpDeviceParams, type Email, type EmailAddress, type EmailAttachment, type GetAttachmentResponse, type GetTotpOtpParams, type KnownTotpDeviceSource, type ListNamespacesResponse, type ListSmsNumbersResponse, type ListTotpDevicesParams, type ListTotpDevicesResponse, MailiskClient, type SearchInboxParams, type SearchInboxResponse, type SearchSmsMessagesParams, type SearchSmsMessagesResponse, type SendVirtualEmailParams, type SendVirtualSmsParams, type SmsMessage, type SmsNumber, type SmtpSettings, type TotpAlgorithm, type TotpDevice, type TotpDeviceSource, type TotpOtpResponse };
package/dist/index.js CHANGED
@@ -131,7 +131,7 @@ var MailiskClient = class {
131
131
  * ```typescript
132
132
  * const device = await client.createTotpDevice({
133
133
  * name: "GitHub staging",
134
- * sharedSecret: "JBSWY3DPEHPK3PXP",
134
+ * shared_secret: "JBSWY3DPEHPK3PXP",
135
135
  * });
136
136
  * ```
137
137
  */
@@ -165,7 +165,7 @@ var MailiskClient = class {
165
165
  * Create a saved TOTP device from a Base32 secret key
166
166
  * ```typescript
167
167
  * const device = await client.createTotpDeviceFromBase32SecretKey({
168
- * base32SecretKey: "JBSWY3DPEHPK3PXP",
168
+ * base32_secret_key: "JBSWY3DPEHPK3PXP",
169
169
  * username: "qa@example.com",
170
170
  * issuer: "GitHub",
171
171
  * });
@@ -181,7 +181,7 @@ var MailiskClient = class {
181
181
  * Create a saved TOTP device from an otpauth URL
182
182
  * ```typescript
183
183
  * const device = await client.createTotpDeviceFromOtpAuthUrl({
184
- * otpAuthUrl: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
184
+ * otp_auth_url: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
185
185
  * });
186
186
  * ```
187
187
  */
@@ -194,11 +194,13 @@ var MailiskClient = class {
194
194
  * @example
195
195
  * Generate a TOTP code from a shared secret
196
196
  * ```typescript
197
- * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP");
197
+ * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP", {
198
+ * min_seconds_until_expire: 10,
199
+ * });
198
200
  * ```
199
201
  */
200
- async getTotpOtpBySharedSecret(sharedSecret) {
201
- return (await this.axiosInstance.post("api/devices/otp", { sharedSecret })).data;
202
+ async getTotpOtpBySharedSecret(sharedSecret, params) {
203
+ return (await this.axiosInstance.post("api/devices/otp", { shared_secret: sharedSecret, ...params })).data;
202
204
  }
203
205
  /**
204
206
  * Generate a TOTP code for a saved device.
@@ -206,11 +208,14 @@ var MailiskClient = class {
206
208
  * @example
207
209
  * Generate a TOTP code for a saved device
208
210
  * ```typescript
209
- * const { code } = await client.getTotpOtpByDeviceId(device.id);
211
+ * const { code } = await client.getTotpOtpByDeviceId(device.id, {
212
+ * min_seconds_until_expire: 10,
213
+ * });
210
214
  * ```
211
215
  */
212
- async getTotpOtpByDeviceId(deviceId) {
213
- return (await this.axiosInstance.get(`api/devices/${deviceId}/otp`)).data;
216
+ async getTotpOtpByDeviceId(deviceId, params) {
217
+ const url = `api/devices/${deviceId}/otp`;
218
+ return params ? (await this.axiosInstance.get(url, { params })).data : (await this.axiosInstance.get(url)).data;
214
219
  }
215
220
  /**
216
221
  * Delete a saved TOTP device.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/mailisk.ts"],"sourcesContent":["export * from \"./mailisk\";\nexport * from \"./mailisk.interfaces\";\n","import axios, { AxiosBasicCredentials, AxiosInstance, AxiosRequestConfig } from \"axios\";\nimport {\n CreateBase32SecretKeyTotpDeviceParams,\n CreateCustomTotpDeviceParams,\n CreateOtpAuthUrlTotpDeviceParams,\n CreateTotpDeviceParams,\n GetAttachmentResponse,\n ListNamespacesResponse,\n ListSmsNumbersResponse,\n ListTotpDevicesParams,\n ListTotpDevicesResponse,\n SearchInboxParams,\n SearchInboxResponse,\n SearchSmsMessagesParams,\n SearchSmsMessagesResponse,\n SendVirtualEmailParams,\n SendVirtualSmsParams,\n SmtpSettings,\n TotpDevice,\n TotpOtpResponse,\n} from \"./mailisk.interfaces\";\nimport nodemailer from \"nodemailer\";\n\nexport class MailiskClient {\n constructor({ apiKey, baseUrl, auth }: { apiKey: string; baseUrl?: string; auth?: AxiosBasicCredentials }) {\n this.axiosInstance = axios.create({\n headers: {\n \"X-Api-Key\": apiKey,\n },\n baseURL: baseUrl || \"https://api.mailisk.com/\",\n auth,\n });\n }\n\n private readonly axiosInstance: AxiosInstance;\n\n /**\n * Search SMS messages sent to a phone number.\n *\n * @example\n * Search for SMS messages sent to a phone number\n * ```typescript\n * const { data: smsMessages } = await client.searchSmsMessages(\"1234567890\");\n * ```\n */\n async searchSmsMessages(\n phoneNumber: string,\n params?: SearchSmsMessagesParams,\n config?: AxiosRequestConfig,\n ): Promise<SearchSmsMessagesResponse> {\n let _params: SearchSmsMessagesParams = { ...params };\n\n // default from timestamp, 15 minutes before starting this request\n if (params?.from_date === undefined || params?.from_date === null) {\n _params.from_date = new Date(Date.now() - 15 * 60 * 1000).toISOString();\n }\n\n // by default wait for sms\n if (params?.wait !== false) {\n _params.wait = true;\n }\n\n let _config = { ...config };\n\n if (config?.maxRedirects === undefined) {\n _config.maxRedirects = 99999;\n }\n\n // by default, wait 5 minutes for emails before timing out\n if (_params.wait && config?.timeout === undefined) {\n _config.timeout = 1000 * 60 * 5;\n }\n\n const requestParams = {\n ..._params,\n from_date: _params.from_date ?? undefined,\n to_date: _params.to_date ?? undefined,\n };\n\n return (\n await this.axiosInstance.get(`api/sms/${phoneNumber}/messages`, {\n ..._config,\n params: requestParams,\n })\n ).data;\n }\n\n /**\n * List all SMS phone numbers associated with the current account.\n *\n * @example\n * List all SMS phone numbers\n * ```typescript\n * const { data: smsNumbers } = await client.listSmsNumbers();\n * ```\n */\n async listSmsNumbers(): Promise<ListSmsNumbersResponse> {\n return (await this.axiosInstance.get(\"api/sms/numbers\")).data;\n }\n\n async sendVirtualSms(params: SendVirtualSmsParams): Promise<void> {\n return (await this.axiosInstance.post(\"api/sms/virtual\", params)).data;\n }\n\n /**\n * List saved TOTP devices.\n *\n * @example\n * List saved TOTP devices for an issuer and username\n * ```typescript\n * const { items: devices } = await client.listTotpDevices({\n * issuer: \"GitHub\",\n * username: \"qa@example.com\",\n * });\n * ```\n */\n async listTotpDevices(params?: ListTotpDevicesParams): Promise<ListTotpDevicesResponse> {\n const requestParams: ListTotpDevicesParams = {\n ...params,\n username: params?.username?.trim(),\n issuer: params?.issuer?.trim(),\n };\n\n return (\n await this.axiosInstance.get(\"api/devices\", {\n params: requestParams,\n })\n ).data;\n }\n\n /**\n * Create a saved TOTP device from a Base32 shared secret using default TOTP settings.\n *\n * @example\n * Create a saved TOTP device from a shared secret\n * ```typescript\n * const device = await client.createTotpDevice({\n * name: \"GitHub staging\",\n * sharedSecret: \"JBSWY3DPEHPK3PXP\",\n * });\n * ```\n */\n async createTotpDevice(params: CreateTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices\", params)).data;\n }\n\n /**\n * Create a saved TOTP device with custom settings.\n *\n * @example\n * Create a saved TOTP device with custom settings\n * ```typescript\n * const device = await client.createCustomTotpDevice({\n * name: \"GitHub staging\",\n * secret: \"JBSWY3DPEHPK3PXP\",\n * username: \"qa@example.com\",\n * issuer: \"GitHub\",\n * digits: 6,\n * period: 30,\n * algorithm: \"SHA1\",\n * });\n * ```\n */\n async createCustomTotpDevice(params: CreateCustomTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/custom\", params)).data;\n }\n\n /**\n * Create a saved TOTP device from a Base32 secret key.\n *\n * @example\n * Create a saved TOTP device from a Base32 secret key\n * ```typescript\n * const device = await client.createTotpDeviceFromBase32SecretKey({\n * base32SecretKey: \"JBSWY3DPEHPK3PXP\",\n * username: \"qa@example.com\",\n * issuer: \"GitHub\",\n * });\n * ```\n */\n async createTotpDeviceFromBase32SecretKey(params: CreateBase32SecretKeyTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/base32-secret-key\", params)).data;\n }\n\n /**\n * Create a saved TOTP device from an otpauth://totp URL.\n *\n * @example\n * Create a saved TOTP device from an otpauth URL\n * ```typescript\n * const device = await client.createTotpDeviceFromOtpAuthUrl({\n * otpAuthUrl: \"otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub\",\n * });\n * ```\n */\n async createTotpDeviceFromOtpAuthUrl(params: CreateOtpAuthUrlTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/otpauth-url\", params)).data;\n }\n\n /**\n * Generate a TOTP code from a shared secret without saving a device.\n *\n * @example\n * Generate a TOTP code from a shared secret\n * ```typescript\n * const { code } = await client.getTotpOtpBySharedSecret(\"JBSWY3DPEHPK3PXP\");\n * ```\n */\n async getTotpOtpBySharedSecret(sharedSecret: string): Promise<TotpOtpResponse> {\n return (await this.axiosInstance.post(\"api/devices/otp\", { sharedSecret })).data;\n }\n\n /**\n * Generate a TOTP code for a saved device.\n *\n * @example\n * Generate a TOTP code for a saved device\n * ```typescript\n * const { code } = await client.getTotpOtpByDeviceId(device.id);\n * ```\n */\n async getTotpOtpByDeviceId(deviceId: string): Promise<TotpOtpResponse> {\n return (await this.axiosInstance.get(`api/devices/${deviceId}/otp`)).data;\n }\n\n /**\n * Delete a saved TOTP device.\n *\n * @example\n * Delete a saved TOTP device\n * ```typescript\n * await client.deleteTotpDevice(device.id);\n * ```\n */\n async deleteTotpDevice(deviceId: string): Promise<void> {\n await this.axiosInstance.delete(`api/devices/${deviceId}`);\n }\n\n /**\n * List all namespaces that belong to the current account (API key).\n */\n async listNamespaces(): Promise<ListNamespacesResponse> {\n return (await this.axiosInstance.get(\"api/namespaces\")).data;\n }\n\n /**\n * Send an email using the Virtual SMTP.\n *\n * These emails can only be sent to valid Mailisk namespaces, i.e. emails that end in @mynamespace.mailisk.net\n *\n * @example\n * For example, sending a test email:\n * ```typescript\n * client.sendVirtualEmail(namespace, {\n * from: \"test@example.com\",\n * to: `john@${namespace}.mailisk.net`,\n * subject: \"This is a test\",\n * text: \"Testing\",\n * });\n * ```\n */\n async sendVirtualEmail(namespace: string, params: SendVirtualEmailParams): Promise<void> {\n const smtpSettings = await this.getSmtpSettings(namespace);\n\n const transport = nodemailer.createTransport({\n host: smtpSettings.data.host,\n port: smtpSettings.data.port,\n secure: false,\n auth: {\n user: smtpSettings.data.username,\n pass: smtpSettings.data.password,\n },\n });\n\n const { from, to, subject, text, html, headers, attachments } = params;\n\n await transport.sendMail({\n from,\n to,\n subject,\n text,\n html,\n headers,\n attachments,\n });\n\n transport.close();\n }\n\n /**\n * Search inbox of a namespace.\n *\n * By default, this calls the api using the `wait` flag. This means the call won't timeout until at least one email is received or 5 minutes pass.\n * It also uses a default `from_timestamp` of **current timestamp - 15 minutes**. This means that older emails will be ignored.\n *\n * Both of these settings can be overriden by passing them in the `params` object.\n *\n * @example\n * Get the latest emails\n * ```typescript\n * const { data: emails } = await client.searchInbox(namespace);\n * ```\n *\n * @example\n * Get the latest emails for a specific email address\n * ```typescript\n * const { data: emails } = await client.searchInbox(namespace, {\n * to_addr_prefix: 'john@mynamespace.mailisk.net'\n * });\n * ```\n *\n * @example\n * Get the last 20 emails in the namespace\n * ```typescript\n * const { data: emails } = await mailisk.searchInbox(namespace, {\n * wait: false,\n * from_timestamp: 0,\n * limit: 20\n * });\n * ```\n */\n async searchInbox(\n namespace: string,\n params?: SearchInboxParams,\n config?: AxiosRequestConfig,\n ): Promise<SearchInboxResponse> {\n let _params = { ...params };\n\n // default from timestamp, 15 minutes before starting this request\n if (params?.from_timestamp === undefined || params?.from_timestamp === null) {\n _params.from_timestamp = Math.floor(new Date().getTime() / 1000) - 15 * 60;\n }\n\n // by default wait for email\n if (params?.wait !== false) {\n _params.wait = true;\n }\n\n let _config = { ...config };\n\n if (config?.maxRedirects === undefined) {\n _config.maxRedirects = 99999;\n }\n\n // by default, wait 5 minutes for emails before timing out\n if (_params.wait && config?.timeout === undefined) {\n _config.timeout = 1000 * 60 * 5;\n }\n\n return (\n await this.axiosInstance.get(`api/emails/${namespace}/inbox`, {\n ..._config,\n params: _params,\n })\n ).data;\n }\n\n /**\n * Get the SMTP settings for a namespace.\n */\n async getSmtpSettings(namespace: string): Promise<SmtpSettings> {\n const result = await this.axiosInstance.get(`api/smtp/${namespace}`);\n return result.data;\n }\n\n async getAttachment(attachmentId: string): Promise<GetAttachmentResponse> {\n const result = await this.axiosInstance.get(`api/attachments/${attachmentId}`);\n return result.data;\n }\n\n /**\n * Download an attachment from an attachment ID.\n *\n * @example\n * Download an attachment from an email\n * ```typescript\n * const attachment = email.attachments[0];\n * const attachmentBuffer = await client.downloadAttachment(attachment.id);\n *\n * // save to file\n * fs.writeFileSync(attachment.filename, attachmentBuffer);\n * ```\n */\n async downloadAttachment(attachmentId: string): Promise<Buffer> {\n const result = await this.getAttachment(attachmentId);\n\n const response = await axios.get(result.data.download_url, { responseType: \"arraybuffer\" });\n return Buffer.from(response.data);\n }\n}\n"],"mappings":"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","names":["axios","nodemailer"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/mailisk.ts"],"sourcesContent":["export * from \"./mailisk\";\nexport * from \"./mailisk.interfaces\";\n","import axios, { AxiosBasicCredentials, AxiosInstance, AxiosRequestConfig } from \"axios\";\nimport {\n CreateBase32SecretKeyTotpDeviceParams,\n CreateCustomTotpDeviceParams,\n CreateOtpAuthUrlTotpDeviceParams,\n CreateTotpDeviceParams,\n GetAttachmentResponse,\n GetTotpOtpParams,\n ListNamespacesResponse,\n ListSmsNumbersResponse,\n ListTotpDevicesParams,\n ListTotpDevicesResponse,\n SearchInboxParams,\n SearchInboxResponse,\n SearchSmsMessagesParams,\n SearchSmsMessagesResponse,\n SendVirtualEmailParams,\n SendVirtualSmsParams,\n SmtpSettings,\n TotpDevice,\n TotpOtpResponse,\n} from \"./mailisk.interfaces\";\nimport nodemailer from \"nodemailer\";\n\nexport class MailiskClient {\n constructor({ apiKey, baseUrl, auth }: { apiKey: string; baseUrl?: string; auth?: AxiosBasicCredentials }) {\n this.axiosInstance = axios.create({\n headers: {\n \"X-Api-Key\": apiKey,\n },\n baseURL: baseUrl || \"https://api.mailisk.com/\",\n auth,\n });\n }\n\n private readonly axiosInstance: AxiosInstance;\n\n /**\n * Search SMS messages sent to a phone number.\n *\n * @example\n * Search for SMS messages sent to a phone number\n * ```typescript\n * const { data: smsMessages } = await client.searchSmsMessages(\"1234567890\");\n * ```\n */\n async searchSmsMessages(\n phoneNumber: string,\n params?: SearchSmsMessagesParams,\n config?: AxiosRequestConfig,\n ): Promise<SearchSmsMessagesResponse> {\n let _params: SearchSmsMessagesParams = { ...params };\n\n // default from timestamp, 15 minutes before starting this request\n if (params?.from_date === undefined || params?.from_date === null) {\n _params.from_date = new Date(Date.now() - 15 * 60 * 1000).toISOString();\n }\n\n // by default wait for sms\n if (params?.wait !== false) {\n _params.wait = true;\n }\n\n let _config = { ...config };\n\n if (config?.maxRedirects === undefined) {\n _config.maxRedirects = 99999;\n }\n\n // by default, wait 5 minutes for emails before timing out\n if (_params.wait && config?.timeout === undefined) {\n _config.timeout = 1000 * 60 * 5;\n }\n\n const requestParams = {\n ..._params,\n from_date: _params.from_date ?? undefined,\n to_date: _params.to_date ?? undefined,\n };\n\n return (\n await this.axiosInstance.get(`api/sms/${phoneNumber}/messages`, {\n ..._config,\n params: requestParams,\n })\n ).data;\n }\n\n /**\n * List all SMS phone numbers associated with the current account.\n *\n * @example\n * List all SMS phone numbers\n * ```typescript\n * const { data: smsNumbers } = await client.listSmsNumbers();\n * ```\n */\n async listSmsNumbers(): Promise<ListSmsNumbersResponse> {\n return (await this.axiosInstance.get(\"api/sms/numbers\")).data;\n }\n\n async sendVirtualSms(params: SendVirtualSmsParams): Promise<void> {\n return (await this.axiosInstance.post(\"api/sms/virtual\", params)).data;\n }\n\n /**\n * List saved TOTP devices.\n *\n * @example\n * List saved TOTP devices for an issuer and username\n * ```typescript\n * const { items: devices } = await client.listTotpDevices({\n * issuer: \"GitHub\",\n * username: \"qa@example.com\",\n * });\n * ```\n */\n async listTotpDevices(params?: ListTotpDevicesParams): Promise<ListTotpDevicesResponse> {\n const requestParams: ListTotpDevicesParams = {\n ...params,\n username: params?.username?.trim(),\n issuer: params?.issuer?.trim(),\n };\n\n return (\n await this.axiosInstance.get(\"api/devices\", {\n params: requestParams,\n })\n ).data;\n }\n\n /**\n * Create a saved TOTP device from a Base32 shared secret using default TOTP settings.\n *\n * @example\n * Create a saved TOTP device from a shared secret\n * ```typescript\n * const device = await client.createTotpDevice({\n * name: \"GitHub staging\",\n * shared_secret: \"JBSWY3DPEHPK3PXP\",\n * });\n * ```\n */\n async createTotpDevice(params: CreateTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices\", params)).data;\n }\n\n /**\n * Create a saved TOTP device with custom settings.\n *\n * @example\n * Create a saved TOTP device with custom settings\n * ```typescript\n * const device = await client.createCustomTotpDevice({\n * name: \"GitHub staging\",\n * secret: \"JBSWY3DPEHPK3PXP\",\n * username: \"qa@example.com\",\n * issuer: \"GitHub\",\n * digits: 6,\n * period: 30,\n * algorithm: \"SHA1\",\n * });\n * ```\n */\n async createCustomTotpDevice(params: CreateCustomTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/custom\", params)).data;\n }\n\n /**\n * Create a saved TOTP device from a Base32 secret key.\n *\n * @example\n * Create a saved TOTP device from a Base32 secret key\n * ```typescript\n * const device = await client.createTotpDeviceFromBase32SecretKey({\n * base32_secret_key: \"JBSWY3DPEHPK3PXP\",\n * username: \"qa@example.com\",\n * issuer: \"GitHub\",\n * });\n * ```\n */\n async createTotpDeviceFromBase32SecretKey(params: CreateBase32SecretKeyTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/base32-secret-key\", params)).data;\n }\n\n /**\n * Create a saved TOTP device from an otpauth://totp URL.\n *\n * @example\n * Create a saved TOTP device from an otpauth URL\n * ```typescript\n * const device = await client.createTotpDeviceFromOtpAuthUrl({\n * otp_auth_url: \"otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub\",\n * });\n * ```\n */\n async createTotpDeviceFromOtpAuthUrl(params: CreateOtpAuthUrlTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/otpauth-url\", params)).data;\n }\n\n /**\n * Generate a TOTP code from a shared secret without saving a device.\n *\n * @example\n * Generate a TOTP code from a shared secret\n * ```typescript\n * const { code } = await client.getTotpOtpBySharedSecret(\"JBSWY3DPEHPK3PXP\", {\n * min_seconds_until_expire: 10,\n * });\n * ```\n */\n async getTotpOtpBySharedSecret(sharedSecret: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse> {\n return (await this.axiosInstance.post(\"api/devices/otp\", { shared_secret: sharedSecret, ...params })).data;\n }\n\n /**\n * Generate a TOTP code for a saved device.\n *\n * @example\n * Generate a TOTP code for a saved device\n * ```typescript\n * const { code } = await client.getTotpOtpByDeviceId(device.id, {\n * min_seconds_until_expire: 10,\n * });\n * ```\n */\n async getTotpOtpByDeviceId(deviceId: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse> {\n const url = `api/devices/${deviceId}/otp`;\n\n return params ? (await this.axiosInstance.get(url, { params })).data : (await this.axiosInstance.get(url)).data;\n }\n\n /**\n * Delete a saved TOTP device.\n *\n * @example\n * Delete a saved TOTP device\n * ```typescript\n * await client.deleteTotpDevice(device.id);\n * ```\n */\n async deleteTotpDevice(deviceId: string): Promise<void> {\n await this.axiosInstance.delete(`api/devices/${deviceId}`);\n }\n\n /**\n * List all namespaces that belong to the current account (API key).\n */\n async listNamespaces(): Promise<ListNamespacesResponse> {\n return (await this.axiosInstance.get(\"api/namespaces\")).data;\n }\n\n /**\n * Send an email using the Virtual SMTP.\n *\n * These emails can only be sent to valid Mailisk namespaces, i.e. emails that end in @mynamespace.mailisk.net\n *\n * @example\n * For example, sending a test email:\n * ```typescript\n * client.sendVirtualEmail(namespace, {\n * from: \"test@example.com\",\n * to: `john@${namespace}.mailisk.net`,\n * subject: \"This is a test\",\n * text: \"Testing\",\n * });\n * ```\n */\n async sendVirtualEmail(namespace: string, params: SendVirtualEmailParams): Promise<void> {\n const smtpSettings = await this.getSmtpSettings(namespace);\n\n const transport = nodemailer.createTransport({\n host: smtpSettings.data.host,\n port: smtpSettings.data.port,\n secure: false,\n auth: {\n user: smtpSettings.data.username,\n pass: smtpSettings.data.password,\n },\n });\n\n const { from, to, subject, text, html, headers, attachments } = params;\n\n await transport.sendMail({\n from,\n to,\n subject,\n text,\n html,\n headers,\n attachments,\n });\n\n transport.close();\n }\n\n /**\n * Search inbox of a namespace.\n *\n * By default, this calls the api using the `wait` flag. This means the call won't timeout until at least one email is received or 5 minutes pass.\n * It also uses a default `from_timestamp` of **current timestamp - 15 minutes**. This means that older emails will be ignored.\n *\n * Both of these settings can be overriden by passing them in the `params` object.\n *\n * @example\n * Get the latest emails\n * ```typescript\n * const { data: emails } = await client.searchInbox(namespace);\n * ```\n *\n * @example\n * Get the latest emails for a specific email address\n * ```typescript\n * const { data: emails } = await client.searchInbox(namespace, {\n * to_addr_prefix: 'john@mynamespace.mailisk.net'\n * });\n * ```\n *\n * @example\n * Get the last 20 emails in the namespace\n * ```typescript\n * const { data: emails } = await mailisk.searchInbox(namespace, {\n * wait: false,\n * from_timestamp: 0,\n * limit: 20\n * });\n * ```\n */\n async searchInbox(\n namespace: string,\n params?: SearchInboxParams,\n config?: AxiosRequestConfig,\n ): Promise<SearchInboxResponse> {\n let _params = { ...params };\n\n // default from timestamp, 15 minutes before starting this request\n if (params?.from_timestamp === undefined || params?.from_timestamp === null) {\n _params.from_timestamp = Math.floor(new Date().getTime() / 1000) - 15 * 60;\n }\n\n // by default wait for email\n if (params?.wait !== false) {\n _params.wait = true;\n }\n\n let _config = { ...config };\n\n if (config?.maxRedirects === undefined) {\n _config.maxRedirects = 99999;\n }\n\n // by default, wait 5 minutes for emails before timing out\n if (_params.wait && config?.timeout === undefined) {\n _config.timeout = 1000 * 60 * 5;\n }\n\n return (\n await this.axiosInstance.get(`api/emails/${namespace}/inbox`, {\n ..._config,\n params: _params,\n })\n ).data;\n }\n\n /**\n * Get the SMTP settings for a namespace.\n */\n async getSmtpSettings(namespace: string): Promise<SmtpSettings> {\n const result = await this.axiosInstance.get(`api/smtp/${namespace}`);\n return result.data;\n }\n\n async getAttachment(attachmentId: string): Promise<GetAttachmentResponse> {\n const result = await this.axiosInstance.get(`api/attachments/${attachmentId}`);\n return result.data;\n }\n\n /**\n * Download an attachment from an attachment ID.\n *\n * @example\n * Download an attachment from an email\n * ```typescript\n * const attachment = email.attachments[0];\n * const attachmentBuffer = await client.downloadAttachment(attachment.id);\n *\n * // save to file\n * fs.writeFileSync(attachment.filename, attachmentBuffer);\n * ```\n */\n async downloadAttachment(attachmentId: string): Promise<Buffer> {\n const result = await this.getAttachment(attachmentId);\n\n const response = await axios.get(result.data.download_url, { responseType: \"arraybuffer\" });\n return Buffer.from(response.data);\n }\n}\n"],"mappings":"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","names":["axios","nodemailer"]}
package/dist/index.mjs CHANGED
@@ -97,7 +97,7 @@ var MailiskClient = class {
97
97
  * ```typescript
98
98
  * const device = await client.createTotpDevice({
99
99
  * name: "GitHub staging",
100
- * sharedSecret: "JBSWY3DPEHPK3PXP",
100
+ * shared_secret: "JBSWY3DPEHPK3PXP",
101
101
  * });
102
102
  * ```
103
103
  */
@@ -131,7 +131,7 @@ var MailiskClient = class {
131
131
  * Create a saved TOTP device from a Base32 secret key
132
132
  * ```typescript
133
133
  * const device = await client.createTotpDeviceFromBase32SecretKey({
134
- * base32SecretKey: "JBSWY3DPEHPK3PXP",
134
+ * base32_secret_key: "JBSWY3DPEHPK3PXP",
135
135
  * username: "qa@example.com",
136
136
  * issuer: "GitHub",
137
137
  * });
@@ -147,7 +147,7 @@ var MailiskClient = class {
147
147
  * Create a saved TOTP device from an otpauth URL
148
148
  * ```typescript
149
149
  * const device = await client.createTotpDeviceFromOtpAuthUrl({
150
- * otpAuthUrl: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
150
+ * otp_auth_url: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
151
151
  * });
152
152
  * ```
153
153
  */
@@ -160,11 +160,13 @@ var MailiskClient = class {
160
160
  * @example
161
161
  * Generate a TOTP code from a shared secret
162
162
  * ```typescript
163
- * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP");
163
+ * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP", {
164
+ * min_seconds_until_expire: 10,
165
+ * });
164
166
  * ```
165
167
  */
166
- async getTotpOtpBySharedSecret(sharedSecret) {
167
- return (await this.axiosInstance.post("api/devices/otp", { sharedSecret })).data;
168
+ async getTotpOtpBySharedSecret(sharedSecret, params) {
169
+ return (await this.axiosInstance.post("api/devices/otp", { shared_secret: sharedSecret, ...params })).data;
168
170
  }
169
171
  /**
170
172
  * Generate a TOTP code for a saved device.
@@ -172,11 +174,14 @@ var MailiskClient = class {
172
174
  * @example
173
175
  * Generate a TOTP code for a saved device
174
176
  * ```typescript
175
- * const { code } = await client.getTotpOtpByDeviceId(device.id);
177
+ * const { code } = await client.getTotpOtpByDeviceId(device.id, {
178
+ * min_seconds_until_expire: 10,
179
+ * });
176
180
  * ```
177
181
  */
178
- async getTotpOtpByDeviceId(deviceId) {
179
- return (await this.axiosInstance.get(`api/devices/${deviceId}/otp`)).data;
182
+ async getTotpOtpByDeviceId(deviceId, params) {
183
+ const url = `api/devices/${deviceId}/otp`;
184
+ return params ? (await this.axiosInstance.get(url, { params })).data : (await this.axiosInstance.get(url)).data;
180
185
  }
181
186
  /**
182
187
  * Delete a saved TOTP device.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mailisk.ts"],"sourcesContent":["import axios, { AxiosBasicCredentials, AxiosInstance, AxiosRequestConfig } from \"axios\";\nimport {\n CreateBase32SecretKeyTotpDeviceParams,\n CreateCustomTotpDeviceParams,\n CreateOtpAuthUrlTotpDeviceParams,\n CreateTotpDeviceParams,\n GetAttachmentResponse,\n ListNamespacesResponse,\n ListSmsNumbersResponse,\n ListTotpDevicesParams,\n ListTotpDevicesResponse,\n SearchInboxParams,\n SearchInboxResponse,\n SearchSmsMessagesParams,\n SearchSmsMessagesResponse,\n SendVirtualEmailParams,\n SendVirtualSmsParams,\n SmtpSettings,\n TotpDevice,\n TotpOtpResponse,\n} from \"./mailisk.interfaces\";\nimport nodemailer from \"nodemailer\";\n\nexport class MailiskClient {\n constructor({ apiKey, baseUrl, auth }: { apiKey: string; baseUrl?: string; auth?: AxiosBasicCredentials }) {\n this.axiosInstance = axios.create({\n headers: {\n \"X-Api-Key\": apiKey,\n },\n baseURL: baseUrl || \"https://api.mailisk.com/\",\n auth,\n });\n }\n\n private readonly axiosInstance: AxiosInstance;\n\n /**\n * Search SMS messages sent to a phone number.\n *\n * @example\n * Search for SMS messages sent to a phone number\n * ```typescript\n * const { data: smsMessages } = await client.searchSmsMessages(\"1234567890\");\n * ```\n */\n async searchSmsMessages(\n phoneNumber: string,\n params?: SearchSmsMessagesParams,\n config?: AxiosRequestConfig,\n ): Promise<SearchSmsMessagesResponse> {\n let _params: SearchSmsMessagesParams = { ...params };\n\n // default from timestamp, 15 minutes before starting this request\n if (params?.from_date === undefined || params?.from_date === null) {\n _params.from_date = new Date(Date.now() - 15 * 60 * 1000).toISOString();\n }\n\n // by default wait for sms\n if (params?.wait !== false) {\n _params.wait = true;\n }\n\n let _config = { ...config };\n\n if (config?.maxRedirects === undefined) {\n _config.maxRedirects = 99999;\n }\n\n // by default, wait 5 minutes for emails before timing out\n if (_params.wait && config?.timeout === undefined) {\n _config.timeout = 1000 * 60 * 5;\n }\n\n const requestParams = {\n ..._params,\n from_date: _params.from_date ?? undefined,\n to_date: _params.to_date ?? undefined,\n };\n\n return (\n await this.axiosInstance.get(`api/sms/${phoneNumber}/messages`, {\n ..._config,\n params: requestParams,\n })\n ).data;\n }\n\n /**\n * List all SMS phone numbers associated with the current account.\n *\n * @example\n * List all SMS phone numbers\n * ```typescript\n * const { data: smsNumbers } = await client.listSmsNumbers();\n * ```\n */\n async listSmsNumbers(): Promise<ListSmsNumbersResponse> {\n return (await this.axiosInstance.get(\"api/sms/numbers\")).data;\n }\n\n async sendVirtualSms(params: SendVirtualSmsParams): Promise<void> {\n return (await this.axiosInstance.post(\"api/sms/virtual\", params)).data;\n }\n\n /**\n * List saved TOTP devices.\n *\n * @example\n * List saved TOTP devices for an issuer and username\n * ```typescript\n * const { items: devices } = await client.listTotpDevices({\n * issuer: \"GitHub\",\n * username: \"qa@example.com\",\n * });\n * ```\n */\n async listTotpDevices(params?: ListTotpDevicesParams): Promise<ListTotpDevicesResponse> {\n const requestParams: ListTotpDevicesParams = {\n ...params,\n username: params?.username?.trim(),\n issuer: params?.issuer?.trim(),\n };\n\n return (\n await this.axiosInstance.get(\"api/devices\", {\n params: requestParams,\n })\n ).data;\n }\n\n /**\n * Create a saved TOTP device from a Base32 shared secret using default TOTP settings.\n *\n * @example\n * Create a saved TOTP device from a shared secret\n * ```typescript\n * const device = await client.createTotpDevice({\n * name: \"GitHub staging\",\n * sharedSecret: \"JBSWY3DPEHPK3PXP\",\n * });\n * ```\n */\n async createTotpDevice(params: CreateTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices\", params)).data;\n }\n\n /**\n * Create a saved TOTP device with custom settings.\n *\n * @example\n * Create a saved TOTP device with custom settings\n * ```typescript\n * const device = await client.createCustomTotpDevice({\n * name: \"GitHub staging\",\n * secret: \"JBSWY3DPEHPK3PXP\",\n * username: \"qa@example.com\",\n * issuer: \"GitHub\",\n * digits: 6,\n * period: 30,\n * algorithm: \"SHA1\",\n * });\n * ```\n */\n async createCustomTotpDevice(params: CreateCustomTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/custom\", params)).data;\n }\n\n /**\n * Create a saved TOTP device from a Base32 secret key.\n *\n * @example\n * Create a saved TOTP device from a Base32 secret key\n * ```typescript\n * const device = await client.createTotpDeviceFromBase32SecretKey({\n * base32SecretKey: \"JBSWY3DPEHPK3PXP\",\n * username: \"qa@example.com\",\n * issuer: \"GitHub\",\n * });\n * ```\n */\n async createTotpDeviceFromBase32SecretKey(params: CreateBase32SecretKeyTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/base32-secret-key\", params)).data;\n }\n\n /**\n * Create a saved TOTP device from an otpauth://totp URL.\n *\n * @example\n * Create a saved TOTP device from an otpauth URL\n * ```typescript\n * const device = await client.createTotpDeviceFromOtpAuthUrl({\n * otpAuthUrl: \"otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub\",\n * });\n * ```\n */\n async createTotpDeviceFromOtpAuthUrl(params: CreateOtpAuthUrlTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/otpauth-url\", params)).data;\n }\n\n /**\n * Generate a TOTP code from a shared secret without saving a device.\n *\n * @example\n * Generate a TOTP code from a shared secret\n * ```typescript\n * const { code } = await client.getTotpOtpBySharedSecret(\"JBSWY3DPEHPK3PXP\");\n * ```\n */\n async getTotpOtpBySharedSecret(sharedSecret: string): Promise<TotpOtpResponse> {\n return (await this.axiosInstance.post(\"api/devices/otp\", { sharedSecret })).data;\n }\n\n /**\n * Generate a TOTP code for a saved device.\n *\n * @example\n * Generate a TOTP code for a saved device\n * ```typescript\n * const { code } = await client.getTotpOtpByDeviceId(device.id);\n * ```\n */\n async getTotpOtpByDeviceId(deviceId: string): Promise<TotpOtpResponse> {\n return (await this.axiosInstance.get(`api/devices/${deviceId}/otp`)).data;\n }\n\n /**\n * Delete a saved TOTP device.\n *\n * @example\n * Delete a saved TOTP device\n * ```typescript\n * await client.deleteTotpDevice(device.id);\n * ```\n */\n async deleteTotpDevice(deviceId: string): Promise<void> {\n await this.axiosInstance.delete(`api/devices/${deviceId}`);\n }\n\n /**\n * List all namespaces that belong to the current account (API key).\n */\n async listNamespaces(): Promise<ListNamespacesResponse> {\n return (await this.axiosInstance.get(\"api/namespaces\")).data;\n }\n\n /**\n * Send an email using the Virtual SMTP.\n *\n * These emails can only be sent to valid Mailisk namespaces, i.e. emails that end in @mynamespace.mailisk.net\n *\n * @example\n * For example, sending a test email:\n * ```typescript\n * client.sendVirtualEmail(namespace, {\n * from: \"test@example.com\",\n * to: `john@${namespace}.mailisk.net`,\n * subject: \"This is a test\",\n * text: \"Testing\",\n * });\n * ```\n */\n async sendVirtualEmail(namespace: string, params: SendVirtualEmailParams): Promise<void> {\n const smtpSettings = await this.getSmtpSettings(namespace);\n\n const transport = nodemailer.createTransport({\n host: smtpSettings.data.host,\n port: smtpSettings.data.port,\n secure: false,\n auth: {\n user: smtpSettings.data.username,\n pass: smtpSettings.data.password,\n },\n });\n\n const { from, to, subject, text, html, headers, attachments } = params;\n\n await transport.sendMail({\n from,\n to,\n subject,\n text,\n html,\n headers,\n attachments,\n });\n\n transport.close();\n }\n\n /**\n * Search inbox of a namespace.\n *\n * By default, this calls the api using the `wait` flag. This means the call won't timeout until at least one email is received or 5 minutes pass.\n * It also uses a default `from_timestamp` of **current timestamp - 15 minutes**. This means that older emails will be ignored.\n *\n * Both of these settings can be overriden by passing them in the `params` object.\n *\n * @example\n * Get the latest emails\n * ```typescript\n * const { data: emails } = await client.searchInbox(namespace);\n * ```\n *\n * @example\n * Get the latest emails for a specific email address\n * ```typescript\n * const { data: emails } = await client.searchInbox(namespace, {\n * to_addr_prefix: 'john@mynamespace.mailisk.net'\n * });\n * ```\n *\n * @example\n * Get the last 20 emails in the namespace\n * ```typescript\n * const { data: emails } = await mailisk.searchInbox(namespace, {\n * wait: false,\n * from_timestamp: 0,\n * limit: 20\n * });\n * ```\n */\n async searchInbox(\n namespace: string,\n params?: SearchInboxParams,\n config?: AxiosRequestConfig,\n ): Promise<SearchInboxResponse> {\n let _params = { ...params };\n\n // default from timestamp, 15 minutes before starting this request\n if (params?.from_timestamp === undefined || params?.from_timestamp === null) {\n _params.from_timestamp = Math.floor(new Date().getTime() / 1000) - 15 * 60;\n }\n\n // by default wait for email\n if (params?.wait !== false) {\n _params.wait = true;\n }\n\n let _config = { ...config };\n\n if (config?.maxRedirects === undefined) {\n _config.maxRedirects = 99999;\n }\n\n // by default, wait 5 minutes for emails before timing out\n if (_params.wait && config?.timeout === undefined) {\n _config.timeout = 1000 * 60 * 5;\n }\n\n return (\n await this.axiosInstance.get(`api/emails/${namespace}/inbox`, {\n ..._config,\n params: _params,\n })\n ).data;\n }\n\n /**\n * Get the SMTP settings for a namespace.\n */\n async getSmtpSettings(namespace: string): Promise<SmtpSettings> {\n const result = await this.axiosInstance.get(`api/smtp/${namespace}`);\n return result.data;\n }\n\n async getAttachment(attachmentId: string): Promise<GetAttachmentResponse> {\n const result = await this.axiosInstance.get(`api/attachments/${attachmentId}`);\n return result.data;\n }\n\n /**\n * Download an attachment from an attachment ID.\n *\n * @example\n * Download an attachment from an email\n * ```typescript\n * const attachment = email.attachments[0];\n * const attachmentBuffer = await client.downloadAttachment(attachment.id);\n *\n * // save to file\n * fs.writeFileSync(attachment.filename, attachmentBuffer);\n * ```\n */\n async downloadAttachment(attachmentId: string): Promise<Buffer> {\n const result = await this.getAttachment(attachmentId);\n\n const response = await axios.get(result.data.download_url, { responseType: \"arraybuffer\" });\n return Buffer.from(response.data);\n }\n}\n"],"mappings":";;;;AAAA,OAAO,WAAyE;AAqBhF,OAAO,gBAAgB;AAEhB,IAAM,gBAAN,MAAoB;AAAA,EAvB3B,OAuB2B;AAAA;AAAA;AAAA,EACzB,YAAY,EAAE,QAAQ,SAAS,KAAK,GAAuE;AACzG,SAAK,gBAAgB,MAAM,OAAO;AAAA,MAChC,SAAS;AAAA,QACP,aAAa;AAAA,MACf;AAAA,MACA,SAAS,WAAW;AAAA,MACpB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWjB,MAAM,kBACJ,aACA,QACA,QACoC;AACpC,QAAI,UAAmC,EAAE,GAAG,OAAO;AAGnD,QAAI,QAAQ,cAAc,UAAa,QAAQ,cAAc,MAAM;AACjE,cAAQ,YAAY,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,GAAI,EAAE,YAAY;AAAA,IACxE;AAGA,QAAI,QAAQ,SAAS,OAAO;AAC1B,cAAQ,OAAO;AAAA,IACjB;AAEA,QAAI,UAAU,EAAE,GAAG,OAAO;AAE1B,QAAI,QAAQ,iBAAiB,QAAW;AACtC,cAAQ,eAAe;AAAA,IACzB;AAGA,QAAI,QAAQ,QAAQ,QAAQ,YAAY,QAAW;AACjD,cAAQ,UAAU,MAAO,KAAK;AAAA,IAChC;AAEA,UAAM,gBAAgB;AAAA,MACpB,GAAG;AAAA,MACH,WAAW,QAAQ,aAAa;AAAA,MAChC,SAAS,QAAQ,WAAW;AAAA,IAC9B;AAEA,YACE,MAAM,KAAK,cAAc,IAAI,WAAW,WAAW,aAAa;AAAA,MAC9D,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC,GACD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,iBAAkD;AACtD,YAAQ,MAAM,KAAK,cAAc,IAAI,iBAAiB,GAAG;AAAA,EAC3D;AAAA,EAEA,MAAM,eAAe,QAA6C;AAChE,YAAQ,MAAM,KAAK,cAAc,KAAK,mBAAmB,MAAM,GAAG;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,gBAAgB,QAAkE;AACtF,UAAM,gBAAuC;AAAA,MAC3C,GAAG;AAAA,MACH,UAAU,QAAQ,UAAU,KAAK;AAAA,MACjC,QAAQ,QAAQ,QAAQ,KAAK;AAAA,IAC/B;AAEA,YACE,MAAM,KAAK,cAAc,IAAI,eAAe;AAAA,MAC1C,QAAQ;AAAA,IACV,CAAC,GACD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,iBAAiB,QAAqD;AAC1E,YAAQ,MAAM,KAAK,cAAc,KAAK,eAAe,MAAM,GAAG;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAM,uBAAuB,QAA2D;AACtF,YAAQ,MAAM,KAAK,cAAc,KAAK,sBAAsB,MAAM,GAAG;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,oCAAoC,QAAoE;AAC5G,YAAQ,MAAM,KAAK,cAAc,KAAK,iCAAiC,MAAM,GAAG;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,+BAA+B,QAA+D;AAClG,YAAQ,MAAM,KAAK,cAAc,KAAK,2BAA2B,MAAM,GAAG;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,yBAAyB,cAAgD;AAC7E,YAAQ,MAAM,KAAK,cAAc,KAAK,mBAAmB,EAAE,aAAa,CAAC,GAAG;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,qBAAqB,UAA4C;AACrE,YAAQ,MAAM,KAAK,cAAc,IAAI,eAAe,QAAQ,MAAM,GAAG;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,iBAAiB,UAAiC;AACtD,UAAM,KAAK,cAAc,OAAO,eAAe,QAAQ,EAAE;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAkD;AACtD,YAAQ,MAAM,KAAK,cAAc,IAAI,gBAAgB,GAAG;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,iBAAiB,WAAmB,QAA+C;AACvF,UAAM,eAAe,MAAM,KAAK,gBAAgB,SAAS;AAEzD,UAAM,YAAY,WAAW,gBAAgB;AAAA,MAC3C,MAAM,aAAa,KAAK;AAAA,MACxB,MAAM,aAAa,KAAK;AAAA,MACxB,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,MAAM,aAAa,KAAK;AAAA,QACxB,MAAM,aAAa,KAAK;AAAA,MAC1B;AAAA,IACF,CAAC;AAED,UAAM,EAAE,MAAM,IAAI,SAAS,MAAM,MAAM,SAAS,YAAY,IAAI;AAEhE,UAAM,UAAU,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,cAAU,MAAM;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCA,MAAM,YACJ,WACA,QACA,QAC8B;AAC9B,QAAI,UAAU,EAAE,GAAG,OAAO;AAG1B,QAAI,QAAQ,mBAAmB,UAAa,QAAQ,mBAAmB,MAAM;AAC3E,cAAQ,iBAAiB,KAAK,OAAM,oBAAI,KAAK,GAAE,QAAQ,IAAI,GAAI,IAAI,KAAK;AAAA,IAC1E;AAGA,QAAI,QAAQ,SAAS,OAAO;AAC1B,cAAQ,OAAO;AAAA,IACjB;AAEA,QAAI,UAAU,EAAE,GAAG,OAAO;AAE1B,QAAI,QAAQ,iBAAiB,QAAW;AACtC,cAAQ,eAAe;AAAA,IACzB;AAGA,QAAI,QAAQ,QAAQ,QAAQ,YAAY,QAAW;AACjD,cAAQ,UAAU,MAAO,KAAK;AAAA,IAChC;AAEA,YACE,MAAM,KAAK,cAAc,IAAI,cAAc,SAAS,UAAU;AAAA,MAC5D,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC,GACD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgB,WAA0C;AAC9D,UAAM,SAAS,MAAM,KAAK,cAAc,IAAI,YAAY,SAAS,EAAE;AACnE,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,cAAc,cAAsD;AACxE,UAAM,SAAS,MAAM,KAAK,cAAc,IAAI,mBAAmB,YAAY,EAAE;AAC7E,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,mBAAmB,cAAuC;AAC9D,UAAM,SAAS,MAAM,KAAK,cAAc,YAAY;AAEpD,UAAM,WAAW,MAAM,MAAM,IAAI,OAAO,KAAK,cAAc,EAAE,cAAc,cAAc,CAAC;AAC1F,WAAO,OAAO,KAAK,SAAS,IAAI;AAAA,EAClC;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/mailisk.ts"],"sourcesContent":["import axios, { AxiosBasicCredentials, AxiosInstance, AxiosRequestConfig } from \"axios\";\nimport {\n CreateBase32SecretKeyTotpDeviceParams,\n CreateCustomTotpDeviceParams,\n CreateOtpAuthUrlTotpDeviceParams,\n CreateTotpDeviceParams,\n GetAttachmentResponse,\n GetTotpOtpParams,\n ListNamespacesResponse,\n ListSmsNumbersResponse,\n ListTotpDevicesParams,\n ListTotpDevicesResponse,\n SearchInboxParams,\n SearchInboxResponse,\n SearchSmsMessagesParams,\n SearchSmsMessagesResponse,\n SendVirtualEmailParams,\n SendVirtualSmsParams,\n SmtpSettings,\n TotpDevice,\n TotpOtpResponse,\n} from \"./mailisk.interfaces\";\nimport nodemailer from \"nodemailer\";\n\nexport class MailiskClient {\n constructor({ apiKey, baseUrl, auth }: { apiKey: string; baseUrl?: string; auth?: AxiosBasicCredentials }) {\n this.axiosInstance = axios.create({\n headers: {\n \"X-Api-Key\": apiKey,\n },\n baseURL: baseUrl || \"https://api.mailisk.com/\",\n auth,\n });\n }\n\n private readonly axiosInstance: AxiosInstance;\n\n /**\n * Search SMS messages sent to a phone number.\n *\n * @example\n * Search for SMS messages sent to a phone number\n * ```typescript\n * const { data: smsMessages } = await client.searchSmsMessages(\"1234567890\");\n * ```\n */\n async searchSmsMessages(\n phoneNumber: string,\n params?: SearchSmsMessagesParams,\n config?: AxiosRequestConfig,\n ): Promise<SearchSmsMessagesResponse> {\n let _params: SearchSmsMessagesParams = { ...params };\n\n // default from timestamp, 15 minutes before starting this request\n if (params?.from_date === undefined || params?.from_date === null) {\n _params.from_date = new Date(Date.now() - 15 * 60 * 1000).toISOString();\n }\n\n // by default wait for sms\n if (params?.wait !== false) {\n _params.wait = true;\n }\n\n let _config = { ...config };\n\n if (config?.maxRedirects === undefined) {\n _config.maxRedirects = 99999;\n }\n\n // by default, wait 5 minutes for emails before timing out\n if (_params.wait && config?.timeout === undefined) {\n _config.timeout = 1000 * 60 * 5;\n }\n\n const requestParams = {\n ..._params,\n from_date: _params.from_date ?? undefined,\n to_date: _params.to_date ?? undefined,\n };\n\n return (\n await this.axiosInstance.get(`api/sms/${phoneNumber}/messages`, {\n ..._config,\n params: requestParams,\n })\n ).data;\n }\n\n /**\n * List all SMS phone numbers associated with the current account.\n *\n * @example\n * List all SMS phone numbers\n * ```typescript\n * const { data: smsNumbers } = await client.listSmsNumbers();\n * ```\n */\n async listSmsNumbers(): Promise<ListSmsNumbersResponse> {\n return (await this.axiosInstance.get(\"api/sms/numbers\")).data;\n }\n\n async sendVirtualSms(params: SendVirtualSmsParams): Promise<void> {\n return (await this.axiosInstance.post(\"api/sms/virtual\", params)).data;\n }\n\n /**\n * List saved TOTP devices.\n *\n * @example\n * List saved TOTP devices for an issuer and username\n * ```typescript\n * const { items: devices } = await client.listTotpDevices({\n * issuer: \"GitHub\",\n * username: \"qa@example.com\",\n * });\n * ```\n */\n async listTotpDevices(params?: ListTotpDevicesParams): Promise<ListTotpDevicesResponse> {\n const requestParams: ListTotpDevicesParams = {\n ...params,\n username: params?.username?.trim(),\n issuer: params?.issuer?.trim(),\n };\n\n return (\n await this.axiosInstance.get(\"api/devices\", {\n params: requestParams,\n })\n ).data;\n }\n\n /**\n * Create a saved TOTP device from a Base32 shared secret using default TOTP settings.\n *\n * @example\n * Create a saved TOTP device from a shared secret\n * ```typescript\n * const device = await client.createTotpDevice({\n * name: \"GitHub staging\",\n * shared_secret: \"JBSWY3DPEHPK3PXP\",\n * });\n * ```\n */\n async createTotpDevice(params: CreateTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices\", params)).data;\n }\n\n /**\n * Create a saved TOTP device with custom settings.\n *\n * @example\n * Create a saved TOTP device with custom settings\n * ```typescript\n * const device = await client.createCustomTotpDevice({\n * name: \"GitHub staging\",\n * secret: \"JBSWY3DPEHPK3PXP\",\n * username: \"qa@example.com\",\n * issuer: \"GitHub\",\n * digits: 6,\n * period: 30,\n * algorithm: \"SHA1\",\n * });\n * ```\n */\n async createCustomTotpDevice(params: CreateCustomTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/custom\", params)).data;\n }\n\n /**\n * Create a saved TOTP device from a Base32 secret key.\n *\n * @example\n * Create a saved TOTP device from a Base32 secret key\n * ```typescript\n * const device = await client.createTotpDeviceFromBase32SecretKey({\n * base32_secret_key: \"JBSWY3DPEHPK3PXP\",\n * username: \"qa@example.com\",\n * issuer: \"GitHub\",\n * });\n * ```\n */\n async createTotpDeviceFromBase32SecretKey(params: CreateBase32SecretKeyTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/base32-secret-key\", params)).data;\n }\n\n /**\n * Create a saved TOTP device from an otpauth://totp URL.\n *\n * @example\n * Create a saved TOTP device from an otpauth URL\n * ```typescript\n * const device = await client.createTotpDeviceFromOtpAuthUrl({\n * otp_auth_url: \"otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub\",\n * });\n * ```\n */\n async createTotpDeviceFromOtpAuthUrl(params: CreateOtpAuthUrlTotpDeviceParams): Promise<TotpDevice> {\n return (await this.axiosInstance.post(\"api/devices/otpauth-url\", params)).data;\n }\n\n /**\n * Generate a TOTP code from a shared secret without saving a device.\n *\n * @example\n * Generate a TOTP code from a shared secret\n * ```typescript\n * const { code } = await client.getTotpOtpBySharedSecret(\"JBSWY3DPEHPK3PXP\", {\n * min_seconds_until_expire: 10,\n * });\n * ```\n */\n async getTotpOtpBySharedSecret(sharedSecret: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse> {\n return (await this.axiosInstance.post(\"api/devices/otp\", { shared_secret: sharedSecret, ...params })).data;\n }\n\n /**\n * Generate a TOTP code for a saved device.\n *\n * @example\n * Generate a TOTP code for a saved device\n * ```typescript\n * const { code } = await client.getTotpOtpByDeviceId(device.id, {\n * min_seconds_until_expire: 10,\n * });\n * ```\n */\n async getTotpOtpByDeviceId(deviceId: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse> {\n const url = `api/devices/${deviceId}/otp`;\n\n return params ? (await this.axiosInstance.get(url, { params })).data : (await this.axiosInstance.get(url)).data;\n }\n\n /**\n * Delete a saved TOTP device.\n *\n * @example\n * Delete a saved TOTP device\n * ```typescript\n * await client.deleteTotpDevice(device.id);\n * ```\n */\n async deleteTotpDevice(deviceId: string): Promise<void> {\n await this.axiosInstance.delete(`api/devices/${deviceId}`);\n }\n\n /**\n * List all namespaces that belong to the current account (API key).\n */\n async listNamespaces(): Promise<ListNamespacesResponse> {\n return (await this.axiosInstance.get(\"api/namespaces\")).data;\n }\n\n /**\n * Send an email using the Virtual SMTP.\n *\n * These emails can only be sent to valid Mailisk namespaces, i.e. emails that end in @mynamespace.mailisk.net\n *\n * @example\n * For example, sending a test email:\n * ```typescript\n * client.sendVirtualEmail(namespace, {\n * from: \"test@example.com\",\n * to: `john@${namespace}.mailisk.net`,\n * subject: \"This is a test\",\n * text: \"Testing\",\n * });\n * ```\n */\n async sendVirtualEmail(namespace: string, params: SendVirtualEmailParams): Promise<void> {\n const smtpSettings = await this.getSmtpSettings(namespace);\n\n const transport = nodemailer.createTransport({\n host: smtpSettings.data.host,\n port: smtpSettings.data.port,\n secure: false,\n auth: {\n user: smtpSettings.data.username,\n pass: smtpSettings.data.password,\n },\n });\n\n const { from, to, subject, text, html, headers, attachments } = params;\n\n await transport.sendMail({\n from,\n to,\n subject,\n text,\n html,\n headers,\n attachments,\n });\n\n transport.close();\n }\n\n /**\n * Search inbox of a namespace.\n *\n * By default, this calls the api using the `wait` flag. This means the call won't timeout until at least one email is received or 5 minutes pass.\n * It also uses a default `from_timestamp` of **current timestamp - 15 minutes**. This means that older emails will be ignored.\n *\n * Both of these settings can be overriden by passing them in the `params` object.\n *\n * @example\n * Get the latest emails\n * ```typescript\n * const { data: emails } = await client.searchInbox(namespace);\n * ```\n *\n * @example\n * Get the latest emails for a specific email address\n * ```typescript\n * const { data: emails } = await client.searchInbox(namespace, {\n * to_addr_prefix: 'john@mynamespace.mailisk.net'\n * });\n * ```\n *\n * @example\n * Get the last 20 emails in the namespace\n * ```typescript\n * const { data: emails } = await mailisk.searchInbox(namespace, {\n * wait: false,\n * from_timestamp: 0,\n * limit: 20\n * });\n * ```\n */\n async searchInbox(\n namespace: string,\n params?: SearchInboxParams,\n config?: AxiosRequestConfig,\n ): Promise<SearchInboxResponse> {\n let _params = { ...params };\n\n // default from timestamp, 15 minutes before starting this request\n if (params?.from_timestamp === undefined || params?.from_timestamp === null) {\n _params.from_timestamp = Math.floor(new Date().getTime() / 1000) - 15 * 60;\n }\n\n // by default wait for email\n if (params?.wait !== false) {\n _params.wait = true;\n }\n\n let _config = { ...config };\n\n if (config?.maxRedirects === undefined) {\n _config.maxRedirects = 99999;\n }\n\n // by default, wait 5 minutes for emails before timing out\n if (_params.wait && config?.timeout === undefined) {\n _config.timeout = 1000 * 60 * 5;\n }\n\n return (\n await this.axiosInstance.get(`api/emails/${namespace}/inbox`, {\n ..._config,\n params: _params,\n })\n ).data;\n }\n\n /**\n * Get the SMTP settings for a namespace.\n */\n async getSmtpSettings(namespace: string): Promise<SmtpSettings> {\n const result = await this.axiosInstance.get(`api/smtp/${namespace}`);\n return result.data;\n }\n\n async getAttachment(attachmentId: string): Promise<GetAttachmentResponse> {\n const result = await this.axiosInstance.get(`api/attachments/${attachmentId}`);\n return result.data;\n }\n\n /**\n * Download an attachment from an attachment ID.\n *\n * @example\n * Download an attachment from an email\n * ```typescript\n * const attachment = email.attachments[0];\n * const attachmentBuffer = await client.downloadAttachment(attachment.id);\n *\n * // save to file\n * fs.writeFileSync(attachment.filename, attachmentBuffer);\n * ```\n */\n async downloadAttachment(attachmentId: string): Promise<Buffer> {\n const result = await this.getAttachment(attachmentId);\n\n const response = await axios.get(result.data.download_url, { responseType: \"arraybuffer\" });\n return Buffer.from(response.data);\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mailisk",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "Mailisk library for NodeJS",
5
5
  "keywords": [
6
6
  "mailisk",
@@ -258,7 +258,7 @@ export interface TotpDevice {
258
258
  period: number;
259
259
  algorithm: TotpAlgorithm;
260
260
  source: TotpDeviceSource;
261
- expiresAt?: string | null;
261
+ expires_at?: string | null;
262
262
  created_at: string;
263
263
  updated_at: string;
264
264
  }
@@ -282,11 +282,11 @@ export interface ListTotpDevicesResponse {
282
282
 
283
283
  export interface CreateTotpDeviceParams {
284
284
  /** Base32 shared secret. Uses default TOTP settings. */
285
- sharedSecret: string;
285
+ shared_secret: string;
286
286
  /** Optional saved-device display name. Max 120 characters. */
287
287
  name?: string;
288
288
  /** Future ISO timestamp after which the saved device expires. */
289
- expiresAt?: string;
289
+ expires_at?: string;
290
290
  }
291
291
 
292
292
  export interface CreateCustomTotpDeviceParams {
@@ -305,12 +305,12 @@ export interface CreateCustomTotpDeviceParams {
305
305
  /** Hashing algorithm. */
306
306
  algorithm?: TotpAlgorithm;
307
307
  /** Future ISO timestamp after which the saved device expires. */
308
- expiresAt?: string;
308
+ expires_at?: string;
309
309
  }
310
310
 
311
311
  export interface CreateBase32SecretKeyTotpDeviceParams {
312
312
  /** Base32 shared secret key. */
313
- base32SecretKey: string;
313
+ base32_secret_key: string;
314
314
  /** Optional saved-device display name. Max 120 characters. */
315
315
  name?: string;
316
316
  /** Account label. Max 240 characters. */
@@ -324,12 +324,12 @@ export interface CreateBase32SecretKeyTotpDeviceParams {
324
324
  /** Hashing algorithm. */
325
325
  algorithm?: TotpAlgorithm;
326
326
  /** Future ISO timestamp after which the saved device expires. */
327
- expiresAt?: string;
327
+ expires_at?: string;
328
328
  }
329
329
 
330
330
  export interface CreateOtpAuthUrlTotpDeviceParams {
331
331
  /** otpauth://totp URL with a secret query parameter. */
332
- otpAuthUrl: string;
332
+ otp_auth_url: string;
333
333
  /** Optional saved-device display name. Max 120 characters. */
334
334
  name?: string;
335
335
  /** Account label, used when missing from the URL label. Max 240 characters. */
@@ -343,7 +343,12 @@ export interface CreateOtpAuthUrlTotpDeviceParams {
343
343
  /** Hashing algorithm, used when missing from the URL. */
344
344
  algorithm?: TotpAlgorithm;
345
345
  /** Future ISO timestamp after which the saved device expires. */
346
- expiresAt?: string;
346
+ expires_at?: string;
347
+ }
348
+
349
+ export interface GetTotpOtpParams {
350
+ /** Minimum number of seconds the returned OTP should remain valid. Must be >= 0 and less than the TOTP period. */
351
+ min_seconds_until_expire?: number;
347
352
  }
348
353
 
349
354
  export interface TotpOtpResponse {
package/src/mailisk.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  CreateOtpAuthUrlTotpDeviceParams,
6
6
  CreateTotpDeviceParams,
7
7
  GetAttachmentResponse,
8
+ GetTotpOtpParams,
8
9
  ListNamespacesResponse,
9
10
  ListSmsNumbersResponse,
10
11
  ListTotpDevicesParams,
@@ -136,7 +137,7 @@ export class MailiskClient {
136
137
  * ```typescript
137
138
  * const device = await client.createTotpDevice({
138
139
  * name: "GitHub staging",
139
- * sharedSecret: "JBSWY3DPEHPK3PXP",
140
+ * shared_secret: "JBSWY3DPEHPK3PXP",
140
141
  * });
141
142
  * ```
142
143
  */
@@ -172,7 +173,7 @@ export class MailiskClient {
172
173
  * Create a saved TOTP device from a Base32 secret key
173
174
  * ```typescript
174
175
  * const device = await client.createTotpDeviceFromBase32SecretKey({
175
- * base32SecretKey: "JBSWY3DPEHPK3PXP",
176
+ * base32_secret_key: "JBSWY3DPEHPK3PXP",
176
177
  * username: "qa@example.com",
177
178
  * issuer: "GitHub",
178
179
  * });
@@ -189,7 +190,7 @@ export class MailiskClient {
189
190
  * Create a saved TOTP device from an otpauth URL
190
191
  * ```typescript
191
192
  * const device = await client.createTotpDeviceFromOtpAuthUrl({
192
- * otpAuthUrl: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
193
+ * otp_auth_url: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
193
194
  * });
194
195
  * ```
195
196
  */
@@ -203,11 +204,13 @@ export class MailiskClient {
203
204
  * @example
204
205
  * Generate a TOTP code from a shared secret
205
206
  * ```typescript
206
- * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP");
207
+ * const { code } = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP", {
208
+ * min_seconds_until_expire: 10,
209
+ * });
207
210
  * ```
208
211
  */
209
- async getTotpOtpBySharedSecret(sharedSecret: string): Promise<TotpOtpResponse> {
210
- return (await this.axiosInstance.post("api/devices/otp", { sharedSecret })).data;
212
+ async getTotpOtpBySharedSecret(sharedSecret: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse> {
213
+ return (await this.axiosInstance.post("api/devices/otp", { shared_secret: sharedSecret, ...params })).data;
211
214
  }
212
215
 
213
216
  /**
@@ -216,11 +219,15 @@ export class MailiskClient {
216
219
  * @example
217
220
  * Generate a TOTP code for a saved device
218
221
  * ```typescript
219
- * const { code } = await client.getTotpOtpByDeviceId(device.id);
222
+ * const { code } = await client.getTotpOtpByDeviceId(device.id, {
223
+ * min_seconds_until_expire: 10,
224
+ * });
220
225
  * ```
221
226
  */
222
- async getTotpOtpByDeviceId(deviceId: string): Promise<TotpOtpResponse> {
223
- return (await this.axiosInstance.get(`api/devices/${deviceId}/otp`)).data;
227
+ async getTotpOtpByDeviceId(deviceId: string, params?: GetTotpOtpParams): Promise<TotpOtpResponse> {
228
+ const url = `api/devices/${deviceId}/otp`;
229
+
230
+ return params ? (await this.axiosInstance.get(url, { params })).data : (await this.axiosInstance.get(url)).data;
224
231
  }
225
232
 
226
233
  /**
@@ -117,7 +117,7 @@ export const mockTotpDevice = {
117
117
  period: 30,
118
118
  algorithm: "SHA1",
119
119
  source: "custom",
120
- expiresAt: null,
120
+ expires_at: null,
121
121
  created_at: "2026-05-18T12:00:00.000Z",
122
122
  updated_at: "2026-05-18T12:00:00.000Z",
123
123
  };
@@ -331,9 +331,9 @@ describe("MailiskClient", () => {
331
331
  mockPost.mockResolvedValueOnce({ data: mockTotpDevice });
332
332
 
333
333
  const params = {
334
- sharedSecret: "JBSWY3DPEHPK3PXP",
334
+ shared_secret: "JBSWY3DPEHPK3PXP",
335
335
  name: "GitHub staging",
336
- expiresAt: "2026-06-01T12:00:00.000Z",
336
+ expires_at: "2026-06-01T12:00:00.000Z",
337
337
  };
338
338
 
339
339
  const client = new MailiskClient({ apiKey: "test-key" });
@@ -369,7 +369,7 @@ describe("MailiskClient", () => {
369
369
  mockPost.mockResolvedValueOnce({ data: mockTotpDevice });
370
370
 
371
371
  const params = {
372
- base32SecretKey: "JBSWY3DPEHPK3PXP",
372
+ base32_secret_key: "JBSWY3DPEHPK3PXP",
373
373
  username: "qa@example.com",
374
374
  issuer: "GitHub",
375
375
  };
@@ -386,7 +386,7 @@ describe("MailiskClient", () => {
386
386
  mockPost.mockResolvedValueOnce({ data: mockTotpDevice });
387
387
 
388
388
  const params = {
389
- otpAuthUrl: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
389
+ otp_auth_url: "otpauth://totp/GitHub:qa@example.com?secret=JBSWY3DPEHPK3PXP&issuer=GitHub",
390
390
  };
391
391
 
392
392
  const client = new MailiskClient({ apiKey: "test-key" });
@@ -405,7 +405,23 @@ describe("MailiskClient", () => {
405
405
  const client = new MailiskClient({ apiKey: "test-key" });
406
406
  const result = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP");
407
407
 
408
- expect(mockPost).toHaveBeenCalledWith("api/devices/otp", { sharedSecret: "JBSWY3DPEHPK3PXP" });
408
+ expect(mockPost).toHaveBeenCalledWith("api/devices/otp", { shared_secret: "JBSWY3DPEHPK3PXP" });
409
+ expect(result).toEqual(mockTotpOtpResponse);
410
+ });
411
+
412
+ it("should generate a TOTP code from a shared secret with minimum validity", async () => {
413
+ const { mockPost } = setupMockAxios();
414
+ mockPost.mockResolvedValueOnce({ data: mockTotpOtpResponse });
415
+
416
+ const client = new MailiskClient({ apiKey: "test-key" });
417
+ const result = await client.getTotpOtpBySharedSecret("JBSWY3DPEHPK3PXP", {
418
+ min_seconds_until_expire: 10,
419
+ });
420
+
421
+ expect(mockPost).toHaveBeenCalledWith("api/devices/otp", {
422
+ shared_secret: "JBSWY3DPEHPK3PXP",
423
+ min_seconds_until_expire: 10,
424
+ });
409
425
  expect(result).toEqual(mockTotpOtpResponse);
410
426
  });
411
427
 
@@ -419,6 +435,23 @@ describe("MailiskClient", () => {
419
435
  expect(mockGet).toHaveBeenCalledWith("api/devices/9b1f6ec0-b90d-4bd8-8dd0-f6b2d5138273/otp");
420
436
  expect(result).toEqual(mockTotpOtpResponse);
421
437
  });
438
+
439
+ it("should generate a TOTP code for a saved device with minimum validity", async () => {
440
+ const { mockGet } = setupMockAxios();
441
+ mockGet.mockResolvedValueOnce({ data: mockTotpOtpResponse });
442
+
443
+ const client = new MailiskClient({ apiKey: "test-key" });
444
+ const result = await client.getTotpOtpByDeviceId("9b1f6ec0-b90d-4bd8-8dd0-f6b2d5138273", {
445
+ min_seconds_until_expire: 10,
446
+ });
447
+
448
+ expect(mockGet).toHaveBeenCalledWith("api/devices/9b1f6ec0-b90d-4bd8-8dd0-f6b2d5138273/otp", {
449
+ params: {
450
+ min_seconds_until_expire: 10,
451
+ },
452
+ });
453
+ expect(result).toEqual(mockTotpOtpResponse);
454
+ });
422
455
  });
423
456
 
424
457
  describe("deleteTotpDevice", () => {