@doist/todoist-sdk 8.0.1 → 8.1.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.
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PERMISSIONS = void 0;
|
|
14
|
+
exports.TOKEN_ENDPOINT_AUTH_METHODS = exports.PERMISSIONS = void 0;
|
|
4
15
|
exports.getAuthStateParameter = getAuthStateParameter;
|
|
5
16
|
exports.getAuthorizationUrl = getAuthorizationUrl;
|
|
6
17
|
exports.getAuthToken = getAuthToken;
|
|
7
18
|
exports.revokeToken = revokeToken;
|
|
8
19
|
exports.migratePersonalToken = migratePersonalToken;
|
|
20
|
+
exports.registerClient = registerClient;
|
|
9
21
|
const http_client_1 = require("./transport/http-client");
|
|
10
22
|
const uuid_1 = require("uuid");
|
|
11
23
|
const types_1 = require("./types");
|
|
@@ -19,6 +31,12 @@ exports.PERMISSIONS = [
|
|
|
19
31
|
'project:delete',
|
|
20
32
|
'backups:read',
|
|
21
33
|
];
|
|
34
|
+
/** Supported token endpoint authentication methods for dynamic client registration. */
|
|
35
|
+
exports.TOKEN_ENDPOINT_AUTH_METHODS = [
|
|
36
|
+
'client_secret_post',
|
|
37
|
+
'client_secret_basic',
|
|
38
|
+
'none',
|
|
39
|
+
];
|
|
22
40
|
/**
|
|
23
41
|
* Creates a Basic Authentication header value from client credentials.
|
|
24
42
|
* @param clientId - The OAuth client ID
|
|
@@ -48,13 +66,17 @@ function getAuthStateParameter() {
|
|
|
48
66
|
/**
|
|
49
67
|
* Generates the authorization URL for the OAuth2 flow.
|
|
50
68
|
*
|
|
69
|
+
* The `clientId` can be either a traditional client ID string (e.g. from
|
|
70
|
+
* {@link registerClient}) or an HTTPS URL pointing to a client metadata document,
|
|
71
|
+
* as defined in {@link https://drafts.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/ RFC draft-ietf-oauth-client-id-metadata-document}.
|
|
72
|
+
*
|
|
51
73
|
* @example
|
|
52
74
|
* ```typescript
|
|
53
|
-
* const url = getAuthorizationUrl(
|
|
54
|
-
* 'your-client-id',
|
|
55
|
-
* ['data:read', 'task:add'],
|
|
56
|
-
* state
|
|
57
|
-
* )
|
|
75
|
+
* const url = getAuthorizationUrl({
|
|
76
|
+
* clientId: 'your-client-id',
|
|
77
|
+
* permissions: ['data:read', 'task:add'],
|
|
78
|
+
* state,
|
|
79
|
+
* })
|
|
58
80
|
* // Redirect user to url
|
|
59
81
|
* ```
|
|
60
82
|
*
|
|
@@ -66,7 +88,7 @@ function getAuthorizationUrl({ clientId, permissions, state, baseUrl, }) {
|
|
|
66
88
|
throw new Error('At least one scope value should be passed for permissions.');
|
|
67
89
|
}
|
|
68
90
|
const scope = permissions.join(',');
|
|
69
|
-
return `${(0, endpoints_1.getAuthBaseUri)(baseUrl)}${endpoints_1.ENDPOINT_AUTHORIZATION}?client_id=${clientId}&scope=${scope}&state=${state}`;
|
|
91
|
+
return `${(0, endpoints_1.getAuthBaseUri)(baseUrl)}${endpoints_1.ENDPOINT_AUTHORIZATION}?client_id=${encodeURIComponent(clientId)}&scope=${scope}&state=${state}`;
|
|
70
92
|
}
|
|
71
93
|
/**
|
|
72
94
|
* Exchanges an authorization code for an access token.
|
|
@@ -202,3 +224,48 @@ async function migratePersonalToken(args, options) {
|
|
|
202
224
|
throw new types_1.TodoistRequestError('Personal token migration failed.', err.httpStatusCode, err.responseData);
|
|
203
225
|
}
|
|
204
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Registers a new OAuth client via Dynamic Client Registration (RFC 7591).
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const client = await registerClient({
|
|
233
|
+
* redirectUris: ['https://example.com/callback'],
|
|
234
|
+
* clientName: 'My App',
|
|
235
|
+
* scope: ['data:read_write', 'task:add'],
|
|
236
|
+
* })
|
|
237
|
+
* // Use client.clientId and client.clientSecret for OAuth flows
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* @returns The registered client details
|
|
241
|
+
* @throws {@link TodoistRequestError} If the registration fails
|
|
242
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
|
|
243
|
+
*/
|
|
244
|
+
async function registerClient(args, options) {
|
|
245
|
+
var _a, _b;
|
|
246
|
+
const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
|
|
247
|
+
const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
|
|
248
|
+
try {
|
|
249
|
+
const response = await (0, http_client_1.request)({
|
|
250
|
+
httpMethod: 'POST',
|
|
251
|
+
baseUri: (0, endpoints_1.getAuthBaseUri)(baseUrl),
|
|
252
|
+
relativePath: endpoints_1.ENDPOINT_REGISTER,
|
|
253
|
+
apiToken: undefined,
|
|
254
|
+
payload: Object.assign(Object.assign({}, args), { scope: (_a = args.scope) === null || _a === void 0 ? void 0 : _a.join(' ') }),
|
|
255
|
+
customFetch,
|
|
256
|
+
});
|
|
257
|
+
if (!(0, http_client_1.isSuccess)(response) || !((_b = response.data) === null || _b === void 0 ? void 0 : _b.clientId)) {
|
|
258
|
+
throw new types_1.TodoistRequestError('Dynamic client registration failed.', response.status, response.data);
|
|
259
|
+
}
|
|
260
|
+
const _c = response.data, { clientIdIssuedAt, clientSecretExpiresAt, scope } = _c, rest = __rest(_c, ["clientIdIssuedAt", "clientSecretExpiresAt", "scope"]);
|
|
261
|
+
return Object.assign(Object.assign({}, rest), { scope: scope ? scope.split(' ') : undefined, clientIdIssuedAt: clientIdIssuedAt !== undefined ? new Date(clientIdIssuedAt * 1000) : undefined, clientSecretExpiresAt: clientSecretExpiresAt === undefined
|
|
262
|
+
? undefined
|
|
263
|
+
: clientSecretExpiresAt === 0
|
|
264
|
+
? null
|
|
265
|
+
: new Date(clientSecretExpiresAt * 1000) });
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
const err = error;
|
|
269
|
+
throw new types_1.TodoistRequestError('Dynamic client registration failed.', err.httpStatusCode, err.responseData);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ENDPOINT_REST_ID_MAPPINGS = exports.ENDPOINT_REST_EMAILS = exports.ENDPOINT_REST_BACKUPS_DOWNLOAD = exports.ENDPOINT_REST_BACKUPS = exports.ENDPOINT_REST_ACCESS_TOKENS_MIGRATE = exports.ENDPOINT_REST_TEMPLATES_IMPORT_FROM_ID = exports.ENDPOINT_REST_TEMPLATES_IMPORT_FROM_FILE = exports.ENDPOINT_REST_TEMPLATES_CREATE_FROM_FILE = exports.ENDPOINT_REST_TEMPLATES_URL = exports.ENDPOINT_REST_TEMPLATES_FILE = exports.ENDPOINT_REST_TASKS_COMPLETED = exports.ENDPOINT_REST_PROJECTS_MOVE_TO_PERSONAL = exports.ENDPOINT_REST_PROJECTS_MOVE_TO_WORKSPACE = exports.SECTION_UNARCHIVE = exports.SECTION_ARCHIVE = exports.ENDPOINT_REST_PROJECT_JOIN = exports.ENDPOINT_REST_PROJECT_FULL = exports.ENDPOINT_REST_PROJECTS_PERMISSIONS = exports.ENDPOINT_REST_PROJECTS_ARCHIVED_COUNT = exports.PROJECT_UNARCHIVE = exports.PROJECT_ARCHIVE = exports.ENDPOINT_REST_UPLOADS = exports.ENDPOINT_REST_ACTIVITIES = exports.ENDPOINT_REST_PRODUCTIVITY = exports.ENDPOINT_REST_USER = exports.ENDPOINT_REST_PROJECT_COLLABORATORS = exports.ENDPOINT_REST_PROJECTS_ARCHIVED = exports.ENDPOINT_REST_PROJECTS_SEARCH = exports.ENDPOINT_REST_PROJECTS = exports.ENDPOINT_REST_TASK_MOVE = exports.ENDPOINT_REST_TASK_REOPEN = exports.ENDPOINT_REST_TASK_CLOSE = exports.ENDPOINT_REST_LOCATION_REMINDERS = exports.ENDPOINT_REST_REMINDERS = exports.ENDPOINT_REST_COMMENTS = exports.ENDPOINT_REST_LABELS_SHARED_REMOVE = exports.ENDPOINT_REST_LABELS_SHARED_RENAME = exports.ENDPOINT_REST_LABELS_SHARED = exports.ENDPOINT_REST_LABELS_SEARCH = exports.ENDPOINT_REST_LABELS = exports.ENDPOINT_REST_SECTIONS_SEARCH = exports.ENDPOINT_REST_SECTIONS = exports.ENDPOINT_REST_TASKS_COMPLETED_SEARCH = exports.ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE = exports.ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE = exports.ENDPOINT_REST_TASKS_FILTER = exports.ENDPOINT_REST_TASKS = exports.API_BASE_URI = exports.API_VERSION = exports.TODOIST_WEB_URI = void 0;
|
|
4
|
-
exports.ENDPOINT_WORKSPACE_MEMBERS = exports.ENDPOINT_WORKSPACE_USERS = exports.ENDPOINT_WORKSPACE_PLAN_DETAILS = exports.ENDPOINT_WORKSPACE_LOGO = exports.ENDPOINT_WORKSPACE_JOIN = exports.ENDPOINT_WORKSPACE_INVITATIONS_DELETE = exports.ENDPOINT_WORKSPACE_INVITATIONS_ALL = exports.ENDPOINT_WORKSPACE_INVITATIONS = exports.ENDPOINT_REST_WORKSPACES = exports.ENDPOINT_REST_FOLDERS = exports.ENDPOINT_REVOKE = exports.ENDPOINT_GET_TOKEN = exports.ENDPOINT_AUTHORIZATION = exports.ENDPOINT_SYNC = exports.ENDPOINT_SYNC_QUICK_ADD = exports.ENDPOINT_REST_MOVED_IDS = void 0;
|
|
4
|
+
exports.ENDPOINT_WORKSPACE_MEMBERS = exports.ENDPOINT_WORKSPACE_USERS = exports.ENDPOINT_WORKSPACE_PLAN_DETAILS = exports.ENDPOINT_WORKSPACE_LOGO = exports.ENDPOINT_WORKSPACE_JOIN = exports.ENDPOINT_WORKSPACE_INVITATIONS_DELETE = exports.ENDPOINT_WORKSPACE_INVITATIONS_ALL = exports.ENDPOINT_WORKSPACE_INVITATIONS = exports.ENDPOINT_REST_WORKSPACES = exports.ENDPOINT_REST_FOLDERS = exports.ENDPOINT_REGISTER = exports.ENDPOINT_REVOKE = exports.ENDPOINT_GET_TOKEN = exports.ENDPOINT_AUTHORIZATION = exports.ENDPOINT_SYNC = exports.ENDPOINT_SYNC_QUICK_ADD = exports.ENDPOINT_REST_MOVED_IDS = void 0;
|
|
5
5
|
exports.getSyncBaseUri = getSyncBaseUri;
|
|
6
6
|
exports.getAuthBaseUri = getAuthBaseUri;
|
|
7
7
|
exports.getWorkspaceInvitationAcceptEndpoint = getWorkspaceInvitationAcceptEndpoint;
|
|
@@ -84,6 +84,7 @@ exports.ENDPOINT_SYNC = 'sync';
|
|
|
84
84
|
exports.ENDPOINT_AUTHORIZATION = 'authorize';
|
|
85
85
|
exports.ENDPOINT_GET_TOKEN = 'access_token';
|
|
86
86
|
exports.ENDPOINT_REVOKE = 'revoke';
|
|
87
|
+
exports.ENDPOINT_REGISTER = 'register';
|
|
87
88
|
exports.ENDPOINT_REST_FOLDERS = 'folders';
|
|
88
89
|
// Workspace endpoints
|
|
89
90
|
exports.ENDPOINT_REST_WORKSPACES = 'workspaces';
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
1
12
|
import { request, isSuccess } from './transport/http-client.js';
|
|
2
13
|
import { v4 as uuid } from 'uuid';
|
|
3
14
|
import { TodoistRequestError } from './types/index.js';
|
|
4
|
-
import { getAuthBaseUri, getSyncBaseUri, ENDPOINT_AUTHORIZATION, ENDPOINT_GET_TOKEN, ENDPOINT_REVOKE, ENDPOINT_REST_ACCESS_TOKENS_MIGRATE, } from './consts/endpoints.js';
|
|
15
|
+
import { getAuthBaseUri, getSyncBaseUri, ENDPOINT_AUTHORIZATION, ENDPOINT_GET_TOKEN, ENDPOINT_REVOKE, ENDPOINT_REGISTER, ENDPOINT_REST_ACCESS_TOKENS_MIGRATE, } from './consts/endpoints.js';
|
|
5
16
|
/** Available OAuth2 permission scopes. */
|
|
6
17
|
export const PERMISSIONS = [
|
|
7
18
|
'task:add',
|
|
@@ -11,6 +22,12 @@ export const PERMISSIONS = [
|
|
|
11
22
|
'project:delete',
|
|
12
23
|
'backups:read',
|
|
13
24
|
];
|
|
25
|
+
/** Supported token endpoint authentication methods for dynamic client registration. */
|
|
26
|
+
export const TOKEN_ENDPOINT_AUTH_METHODS = [
|
|
27
|
+
'client_secret_post',
|
|
28
|
+
'client_secret_basic',
|
|
29
|
+
'none',
|
|
30
|
+
];
|
|
14
31
|
/**
|
|
15
32
|
* Creates a Basic Authentication header value from client credentials.
|
|
16
33
|
* @param clientId - The OAuth client ID
|
|
@@ -40,13 +57,17 @@ export function getAuthStateParameter() {
|
|
|
40
57
|
/**
|
|
41
58
|
* Generates the authorization URL for the OAuth2 flow.
|
|
42
59
|
*
|
|
60
|
+
* The `clientId` can be either a traditional client ID string (e.g. from
|
|
61
|
+
* {@link registerClient}) or an HTTPS URL pointing to a client metadata document,
|
|
62
|
+
* as defined in {@link https://drafts.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/ RFC draft-ietf-oauth-client-id-metadata-document}.
|
|
63
|
+
*
|
|
43
64
|
* @example
|
|
44
65
|
* ```typescript
|
|
45
|
-
* const url = getAuthorizationUrl(
|
|
46
|
-
* 'your-client-id',
|
|
47
|
-
* ['data:read', 'task:add'],
|
|
48
|
-
* state
|
|
49
|
-
* )
|
|
66
|
+
* const url = getAuthorizationUrl({
|
|
67
|
+
* clientId: 'your-client-id',
|
|
68
|
+
* permissions: ['data:read', 'task:add'],
|
|
69
|
+
* state,
|
|
70
|
+
* })
|
|
50
71
|
* // Redirect user to url
|
|
51
72
|
* ```
|
|
52
73
|
*
|
|
@@ -58,7 +79,7 @@ export function getAuthorizationUrl({ clientId, permissions, state, baseUrl, })
|
|
|
58
79
|
throw new Error('At least one scope value should be passed for permissions.');
|
|
59
80
|
}
|
|
60
81
|
const scope = permissions.join(',');
|
|
61
|
-
return `${getAuthBaseUri(baseUrl)}${ENDPOINT_AUTHORIZATION}?client_id=${clientId}&scope=${scope}&state=${state}`;
|
|
82
|
+
return `${getAuthBaseUri(baseUrl)}${ENDPOINT_AUTHORIZATION}?client_id=${encodeURIComponent(clientId)}&scope=${scope}&state=${state}`;
|
|
62
83
|
}
|
|
63
84
|
/**
|
|
64
85
|
* Exchanges an authorization code for an access token.
|
|
@@ -194,3 +215,48 @@ export async function migratePersonalToken(args, options) {
|
|
|
194
215
|
throw new TodoistRequestError('Personal token migration failed.', err.httpStatusCode, err.responseData);
|
|
195
216
|
}
|
|
196
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Registers a new OAuth client via Dynamic Client Registration (RFC 7591).
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* const client = await registerClient({
|
|
224
|
+
* redirectUris: ['https://example.com/callback'],
|
|
225
|
+
* clientName: 'My App',
|
|
226
|
+
* scope: ['data:read_write', 'task:add'],
|
|
227
|
+
* })
|
|
228
|
+
* // Use client.clientId and client.clientSecret for OAuth flows
|
|
229
|
+
* ```
|
|
230
|
+
*
|
|
231
|
+
* @returns The registered client details
|
|
232
|
+
* @throws {@link TodoistRequestError} If the registration fails
|
|
233
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
|
|
234
|
+
*/
|
|
235
|
+
export async function registerClient(args, options) {
|
|
236
|
+
var _a, _b;
|
|
237
|
+
const baseUrl = options === null || options === void 0 ? void 0 : options.baseUrl;
|
|
238
|
+
const customFetch = options === null || options === void 0 ? void 0 : options.customFetch;
|
|
239
|
+
try {
|
|
240
|
+
const response = await request({
|
|
241
|
+
httpMethod: 'POST',
|
|
242
|
+
baseUri: getAuthBaseUri(baseUrl),
|
|
243
|
+
relativePath: ENDPOINT_REGISTER,
|
|
244
|
+
apiToken: undefined,
|
|
245
|
+
payload: Object.assign(Object.assign({}, args), { scope: (_a = args.scope) === null || _a === void 0 ? void 0 : _a.join(' ') }),
|
|
246
|
+
customFetch,
|
|
247
|
+
});
|
|
248
|
+
if (!isSuccess(response) || !((_b = response.data) === null || _b === void 0 ? void 0 : _b.clientId)) {
|
|
249
|
+
throw new TodoistRequestError('Dynamic client registration failed.', response.status, response.data);
|
|
250
|
+
}
|
|
251
|
+
const _c = response.data, { clientIdIssuedAt, clientSecretExpiresAt, scope } = _c, rest = __rest(_c, ["clientIdIssuedAt", "clientSecretExpiresAt", "scope"]);
|
|
252
|
+
return Object.assign(Object.assign({}, rest), { scope: scope ? scope.split(' ') : undefined, clientIdIssuedAt: clientIdIssuedAt !== undefined ? new Date(clientIdIssuedAt * 1000) : undefined, clientSecretExpiresAt: clientSecretExpiresAt === undefined
|
|
253
|
+
? undefined
|
|
254
|
+
: clientSecretExpiresAt === 0
|
|
255
|
+
? null
|
|
256
|
+
: new Date(clientSecretExpiresAt * 1000) });
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
const err = error;
|
|
260
|
+
throw new TodoistRequestError('Dynamic client registration failed.', err.httpStatusCode, err.responseData);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
@@ -65,6 +65,7 @@ export const ENDPOINT_SYNC = 'sync';
|
|
|
65
65
|
export const ENDPOINT_AUTHORIZATION = 'authorize';
|
|
66
66
|
export const ENDPOINT_GET_TOKEN = 'access_token';
|
|
67
67
|
export const ENDPOINT_REVOKE = 'revoke';
|
|
68
|
+
export const ENDPOINT_REGISTER = 'register';
|
|
68
69
|
export const ENDPOINT_REST_FOLDERS = 'folders';
|
|
69
70
|
// Workspace endpoints
|
|
70
71
|
export const ENDPOINT_REST_WORKSPACES = 'workspaces';
|
|
@@ -13,6 +13,51 @@ export declare const PERMISSIONS: readonly ["task:add", "data:read", "data:read_
|
|
|
13
13
|
* @see {@link https://developer.todoist.com/api/v1/#tag/Authorization}
|
|
14
14
|
*/
|
|
15
15
|
export type Permission = (typeof PERMISSIONS)[number];
|
|
16
|
+
/** Supported token endpoint authentication methods for dynamic client registration. */
|
|
17
|
+
export declare const TOKEN_ENDPOINT_AUTH_METHODS: readonly ["client_secret_post", "client_secret_basic", "none"];
|
|
18
|
+
/**
|
|
19
|
+
* Authentication method used at the token endpoint.
|
|
20
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591#section-2 RFC 7591 Section 2}
|
|
21
|
+
*/
|
|
22
|
+
export type TokenEndpointAuthMethod = (typeof TOKEN_ENDPOINT_AUTH_METHODS)[number];
|
|
23
|
+
/**
|
|
24
|
+
* Parameters for registering a new OAuth client via Dynamic Client Registration.
|
|
25
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
|
|
26
|
+
*/
|
|
27
|
+
export type ClientRegistrationRequest = {
|
|
28
|
+
redirectUris: string[];
|
|
29
|
+
clientName?: string;
|
|
30
|
+
clientUri?: string;
|
|
31
|
+
logoUri?: string;
|
|
32
|
+
scope?: readonly Permission[];
|
|
33
|
+
grantTypes?: string[];
|
|
34
|
+
responseTypes?: string[];
|
|
35
|
+
tokenEndpointAuthMethod?: TokenEndpointAuthMethod;
|
|
36
|
+
};
|
|
37
|
+
type RawClientRegistrationResponse = {
|
|
38
|
+
clientId: string;
|
|
39
|
+
clientSecret?: string;
|
|
40
|
+
clientName: string;
|
|
41
|
+
redirectUris: string[];
|
|
42
|
+
scope?: string;
|
|
43
|
+
grantTypes: string[];
|
|
44
|
+
responseTypes: string[];
|
|
45
|
+
tokenEndpointAuthMethod: string;
|
|
46
|
+
clientIdIssuedAt?: number;
|
|
47
|
+
clientSecretExpiresAt?: number;
|
|
48
|
+
clientUri?: string;
|
|
49
|
+
logoUri?: string;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Response from a successful dynamic client registration.
|
|
53
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.1 RFC 7591 Section 3.2.1}
|
|
54
|
+
*/
|
|
55
|
+
export type ClientRegistrationResponse = Omit<RawClientRegistrationResponse, 'clientIdIssuedAt' | 'clientSecretExpiresAt' | 'scope'> & {
|
|
56
|
+
scope?: Permission[];
|
|
57
|
+
clientIdIssuedAt?: Date;
|
|
58
|
+
/** `null` indicates the client secret never expires. Absent when no secret is issued. */
|
|
59
|
+
clientSecretExpiresAt?: Date | null;
|
|
60
|
+
};
|
|
16
61
|
/**
|
|
17
62
|
* Parameters required to exchange an authorization code for an access token.
|
|
18
63
|
* @see https://developer.todoist.com/api/v1/#tag/Authorization/OAuth
|
|
@@ -80,13 +125,17 @@ export declare function getAuthStateParameter(): string;
|
|
|
80
125
|
/**
|
|
81
126
|
* Generates the authorization URL for the OAuth2 flow.
|
|
82
127
|
*
|
|
128
|
+
* The `clientId` can be either a traditional client ID string (e.g. from
|
|
129
|
+
* {@link registerClient}) or an HTTPS URL pointing to a client metadata document,
|
|
130
|
+
* as defined in {@link https://drafts.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/ RFC draft-ietf-oauth-client-id-metadata-document}.
|
|
131
|
+
*
|
|
83
132
|
* @example
|
|
84
133
|
* ```typescript
|
|
85
|
-
* const url = getAuthorizationUrl(
|
|
86
|
-
* 'your-client-id',
|
|
87
|
-
* ['data:read', 'task:add'],
|
|
88
|
-
* state
|
|
89
|
-
* )
|
|
134
|
+
* const url = getAuthorizationUrl({
|
|
135
|
+
* clientId: 'your-client-id',
|
|
136
|
+
* permissions: ['data:read', 'task:add'],
|
|
137
|
+
* state,
|
|
138
|
+
* })
|
|
90
139
|
* // Redirect user to url
|
|
91
140
|
* ```
|
|
92
141
|
*
|
|
@@ -156,3 +205,22 @@ export declare function revokeToken(args: RevokeTokenRequestArgs, options?: Auth
|
|
|
156
205
|
* @throws {@link TodoistRequestError} If the migration fails
|
|
157
206
|
*/
|
|
158
207
|
export declare function migratePersonalToken(args: MigratePersonalTokenArgs, options?: AuthOptions): Promise<MigratePersonalTokenResponse>;
|
|
208
|
+
/**
|
|
209
|
+
* Registers a new OAuth client via Dynamic Client Registration (RFC 7591).
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* const client = await registerClient({
|
|
214
|
+
* redirectUris: ['https://example.com/callback'],
|
|
215
|
+
* clientName: 'My App',
|
|
216
|
+
* scope: ['data:read_write', 'task:add'],
|
|
217
|
+
* })
|
|
218
|
+
* // Use client.clientId and client.clientSecret for OAuth flows
|
|
219
|
+
* ```
|
|
220
|
+
*
|
|
221
|
+
* @returns The registered client details
|
|
222
|
+
* @throws {@link TodoistRequestError} If the registration fails
|
|
223
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc7591 RFC 7591}
|
|
224
|
+
*/
|
|
225
|
+
export declare function registerClient(args: ClientRegistrationRequest, options?: AuthOptions): Promise<ClientRegistrationResponse>;
|
|
226
|
+
export {};
|
|
@@ -56,6 +56,7 @@ export declare const ENDPOINT_SYNC = "sync";
|
|
|
56
56
|
export declare const ENDPOINT_AUTHORIZATION = "authorize";
|
|
57
57
|
export declare const ENDPOINT_GET_TOKEN = "access_token";
|
|
58
58
|
export declare const ENDPOINT_REVOKE = "revoke";
|
|
59
|
+
export declare const ENDPOINT_REGISTER = "register";
|
|
59
60
|
export declare const ENDPOINT_REST_FOLDERS = "folders";
|
|
60
61
|
export declare const ENDPOINT_REST_WORKSPACES = "workspaces";
|
|
61
62
|
export declare const ENDPOINT_WORKSPACE_INVITATIONS = "workspaces/invitations";
|
package/package.json
CHANGED