diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9a6950b..ab2538e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,11 @@ A note on versioning: This librarys major version will grow with the APIs version number. Breaking changes will be indicated by a change in the minor (or major) version number, and will generally be avoided. +v1.6.3 +------ +* Add server rules API (`instance_rules`) +* Add confirmation email resend API (`email_resend_confirmation`) + v1.6.2 ------ * Fix some issues with datetime conversion diff --git a/TODO.md b/TODO.md index ee85789..164717a 100644 --- a/TODO.md +++ b/TODO.md @@ -30,7 +30,7 @@ Refer to mastodon changelog and API docs for details when implementing, add or m 3.4.0 ----- * [x] Add server rules -* [ ] Add POST /api/v1/emails/confirmations to REST API +* [x] Add POST /api/v1/emails/confirmations to REST API * [ ] Add GET /api/v1/accounts/lookup to REST API * [ ] Add policy param to POST /api/v1/push/subscriptions in REST API * [ ] Add details to error response for POST /api/v1/accounts in REST API diff --git a/docs/index.rst b/docs/index.rst index f1dcacc..2318a98 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -905,7 +905,8 @@ is specified, Mastodon.py defaults to https. .. _auth_request_url(): .. automethod:: Mastodon.auth_request_url .. automethod:: Mastodon.create_account - +.. automethod:: Mastodon.email_resend_confirmation + Versioning ---------- Mastodon.py will check if a certain endpoint is available before doing API @@ -936,6 +937,7 @@ current instance. .. automethod:: Mastodon.instance_peers .. automethod:: Mastodon.instance_health .. automethod:: Mastodon.instance_nodeinfo +.. automethod:: Mastodon.instance_rules Reading data: Timelines ----------------------- @@ -1417,4 +1419,3 @@ about who helped with which particular feature or fix in the changelog. .. toctree:: :maxdepth: -1 :collapse_navigation: False - \ No newline at end of file diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index 14cf174..629a4b2 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py @@ -726,6 +726,15 @@ class Mastodon: return response['access_token'] + @api_version("3.4.0", "3.4.0", "3.4.0") + def email_resend_confirmation(self): + """ + Requests a re-send of the users confirmation mail for an unconfirmed logged in user. + + Only available to the app that the user originally signed up with. + """ + self.__api_request('POST', '/api/v1/emails/confirmations') + ### # Reading data: Instances ### diff --git a/tests/cassettes/test_app_account_create.yaml b/tests/cassettes/test_app_account_create.yaml index 8f7f664..33c6723 100644 --- a/tests/cassettes/test_app_account_create.yaml +++ b/tests/cassettes/test_app_account_create.yaml @@ -18,14 +18,14 @@ interactions: uri: http://localhost:3000/api/v1/apps response: body: - string: '{"id":"2","name":"mastodon.py generated test app","website":null,"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":"gEuKqNuywsaMneO5Ac2jiOwyIxDfAl8vCAEQHQroDEA","client_secret":"WU0JXbe9t289_sIhrlD_m2rTJZWcehTNy60Khq1hFSs","vapid_key":"BIX7IY8wYrdPf5wfG59B5B4CBbpQWmOBr_SI9zEsCDfMGDx8KmPuu-3WP7b-amaekv2NZj3ZSNst9OaqoxXvC1s="}' + string: '{"id":"3","name":"mastodon.py generated test app","website":null,"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":"i5IaOmWav2cZA-GOJt-F2VfATkknbX0R8quGGBpwcTA","client_secret":"MUZ-dt5iJqQZdEug7rSH2L76dWfmbZAiA63n8je_QSg","vapid_key":"BFu6DBpfcm8_h8gm3rHUkfaOLg7azvYN_auFI4KcNuh5SLBVMhTkKKvUaLENtA_c6v5Hmrucvh0WwsN1o9NFQRU="}' headers: Cache-Control: - no-store Content-Security-Policy: - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; - style-src ''self'' http://localhost:3000 ''nonce-Zh318FJnptQQXbYGbr6ipQ==''; + style-src ''self'' http://localhost:3000 ''nonce-PMQM0qLu5SRYCvXeJZ0kQg==''; media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 @@ -35,7 +35,7 @@ interactions: Content-Type: - application/json; charset=utf-8 ETag: - - W/"4ce1f03f00fba44db374be39a911d5c7" + - W/"6d8fcc5bda56fba5337c6b58a9043b2e" Referrer-Policy: - strict-origin-when-cross-origin Transfer-Encoding: @@ -51,9 +51,9 @@ interactions: X-Permitted-Cross-Domain-Policies: - none X-Request-Id: - - 13df349b-78e3-4af3-8362-2036891efa2c + - 32de1904-3319-4b4a-9596-acf1e5ba291c X-Runtime: - - '0.013468' + - '0.024619' X-XSS-Protection: - 1; mode=block status: @@ -74,14 +74,14 @@ interactions: uri: http://localhost:3000/api/v1/instance/ response: body: - string: '{"uri":"localhost:3000","title":"Mastodon","short_description":"","description":"","email":"","version":"4.0.0rc2","urls":{"streaming_api":"ws://localhost:4000"},"stats":{"user_count":4,"status_count":1,"domain_count":0},"thumbnail":"http://localhost:3000/packs/media/images/preview-6399aebd96ccf025654e2977454f168f.png","languages":["en"],"registrations":true,"approval_required":false,"invites_enabled":true,"configuration":{"accounts":{"max_featured_tags":10},"statuses":{"max_characters":500,"max_media_attachments":4,"characters_reserved_per_url":23},"media_attachments":{"supported_mime_types":["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"],"image_size_limit":10485760,"image_matrix_limit":16777216,"video_size_limit":41943040,"video_frame_rate_limit":60,"video_matrix_limit":2304000},"polls":{"max_options":4,"max_characters_per_option":50,"min_expiration":300,"max_expiration":2629746}},"contact_account":null,"rules":[]}' + string: '{"uri":"localhost:3000","title":"Mastodon","short_description":"","description":"","email":"","version":"4.0.0rc2","urls":{"streaming_api":"ws://localhost:4000"},"stats":{"user_count":4,"status_count":5,"domain_count":0},"thumbnail":"http://localhost:3000/packs/media/images/preview-6399aebd96ccf025654e2977454f168f.png","languages":["en"],"registrations":true,"approval_required":false,"invites_enabled":true,"configuration":{"accounts":{"max_featured_tags":10},"statuses":{"max_characters":500,"max_media_attachments":4,"characters_reserved_per_url":23},"media_attachments":{"supported_mime_types":["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"],"image_size_limit":10485760,"image_matrix_limit":16777216,"video_size_limit":41943040,"video_frame_rate_limit":60,"video_matrix_limit":2304000},"polls":{"max_options":4,"max_characters_per_option":50,"min_expiration":300,"max_expiration":2629746}},"contact_account":null,"rules":[]}' headers: Cache-Control: - max-age=180, public Content-Security-Policy: - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; - style-src ''self'' http://localhost:3000 ''nonce-W66NplWHcyKqASWNg0Dssg==''; + style-src ''self'' http://localhost:3000 ''nonce-kSKGlm6hIJpevnUBOkuw6A==''; media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 @@ -91,9 +91,9 @@ interactions: Content-Type: - application/json; charset=utf-8 Date: - - Sun, 13 Nov 2022 16:29:56 GMT + - Fri, 18 Nov 2022 23:10:30 GMT ETag: - - W/"bf317ffab393d8d1da7195269f28968a" + - W/"58e74f5c697f043d86089eae87509b84" Referrer-Policy: - strict-origin-when-cross-origin Transfer-Encoding: @@ -109,16 +109,16 @@ interactions: X-Permitted-Cross-Domain-Policies: - none X-Request-Id: - - 0f6df9ea-ef58-4b94-a0b5-5a41cc140ea4 + - afd24d44-eaee-493a-802e-647a4e9e6f9a X-Runtime: - - '0.012362' + - '0.022642' X-XSS-Protection: - 1; mode=block status: code: 200 message: OK - request: - body: scope=read+write+follow+push&client_id=gEuKqNuywsaMneO5Ac2jiOwyIxDfAl8vCAEQHQroDEA&client_secret=WU0JXbe9t289_sIhrlD_m2rTJZWcehTNy60Khq1hFSs&grant_type=client_credentials + body: scope=read+write+follow+push&client_id=i5IaOmWav2cZA-GOJt-F2VfATkknbX0R8quGGBpwcTA&client_secret=MUZ-dt5iJqQZdEug7rSH2L76dWfmbZAiA63n8je_QSg&grant_type=client_credentials headers: Accept: - '*/*' @@ -136,15 +136,15 @@ interactions: uri: http://localhost:3000/oauth/token response: body: - string: '{"access_token":"hjO121FQ7LARVj6rPCGwBB5ae9q9Qw3qNvJYwKfLIEo","token_type":"Bearer","scope":"read - write follow push","created_at":1668356996}' + string: '{"access_token":"6w7d8CApoQtnKPZ_XX7vr3X68OLc4RZevnzOfopsxU4","token_type":"Bearer","scope":"read + write follow push","created_at":1668813030}' headers: Cache-Control: - no-store Content-Security-Policy: - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; - style-src ''self'' http://localhost:3000 ''nonce-Ky+xWz4IzT8eC/nLsYn9Ug==''; + style-src ''self'' http://localhost:3000 ''nonce-qVLiytlopC8F7NDbA+J3XQ==''; media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 @@ -154,7 +154,7 @@ interactions: Content-Type: - application/json; charset=utf-8 ETag: - - W/"365d6ad17841f9fc108d819b6f80d64f" + - W/"13d9af143daea000a5ee432a619b9736" Pragma: - no-cache Referrer-Policy: @@ -172,23 +172,23 @@ interactions: X-Permitted-Cross-Domain-Policies: - none X-Request-Id: - - 577d694d-e490-4415-992b-da9da0979864 + - 41bcf86f-fd9d-458f-83ea-e173eb0e8eee X-Runtime: - - '0.010756' + - '0.010786' X-XSS-Protection: - 1; mode=block status: code: 200 message: OK - request: - body: username=coolguy27294&password=swordfish&email=email%40localhost27294&agreement=1&locale=en&client_id=gEuKqNuywsaMneO5Ac2jiOwyIxDfAl8vCAEQHQroDEA&client_secret=WU0JXbe9t289_sIhrlD_m2rTJZWcehTNy60Khq1hFSs + body: username=coolguy91663&password=swordfish&email=email%40localhost91663&agreement=1&locale=en&client_id=i5IaOmWav2cZA-GOJt-F2VfATkknbX0R8quGGBpwcTA&client_secret=MUZ-dt5iJqQZdEug7rSH2L76dWfmbZAiA63n8je_QSg headers: Accept: - '*/*' Accept-Encoding: - gzip, deflate Authorization: - - Bearer hjO121FQ7LARVj6rPCGwBB5ae9q9Qw3qNvJYwKfLIEo + - Bearer 6w7d8CApoQtnKPZ_XX7vr3X68OLc4RZevnzOfopsxU4 Connection: - keep-alive Content-Length: @@ -201,15 +201,15 @@ interactions: uri: http://localhost:3000/api/v1/accounts response: body: - string: '{"access_token":"fa6GZxjyPYsGuapcEQqdXpY3r9EDnwaAzY4vahT1GNY","token_type":"Bearer","scope":"read - write follow push","created_at":1668356996}' + string: '{"access_token":"WTJy6jqCcUmPdPRpxGPXGr5tb-u_ZhDZa5BfLrZbR88","token_type":"Bearer","scope":"read + write follow push","created_at":1668813030}' headers: Cache-Control: - no-store Content-Security-Policy: - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; - style-src ''self'' http://localhost:3000 ''nonce-HeTgpdMKCUkyYQyy5dwEcw==''; + style-src ''self'' http://localhost:3000 ''nonce-ZmZ3Nikn0UBUyHH8SPHxmA==''; media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 @@ -219,7 +219,7 @@ interactions: Content-Type: - application/json; charset=utf-8 ETag: - - W/"1ddd115ebd5097ed791b3457e361636a" + - W/"f2275c085ebaec598ae00c838b507999" Pragma: - no-cache Referrer-Policy: @@ -237,9 +237,69 @@ interactions: X-Permitted-Cross-Domain-Policies: - none X-Request-Id: - - 1b2b769a-3a32-440b-aeba-b967967f86e6 + - a2d80241-35a5-48c8-b4c7-1c714869731d X-Runtime: - - '0.088416' + - '0.078012' + X-XSS-Protection: + - 1; mode=block + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Authorization: + - Bearer WTJy6jqCcUmPdPRpxGPXGr5tb-u_ZhDZa5BfLrZbR88 + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - mastodonpy + method: POST + uri: http://localhost:3000/api/v1/emails/confirmations + response: + body: + string: '{}' + headers: + Cache-Control: + - no-store + Content-Security-Policy: + - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src + ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000; + style-src ''self'' http://localhost:3000 ''nonce-7apBIRbCSTiLStbmHNeFgQ==''; + media-src ''self'' https: data: http://localhost:3000; frame-src ''self'' + https:; manifest-src ''self'' http://localhost:3000; connect-src ''self'' + data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000 + ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline'' + ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000; + worker-src ''self'' blob: http://localhost:3000' + Content-Type: + - application/json; charset=utf-8 + ETag: + - W/"44136fa355b3678a1146ad16f7e8649e" + Referrer-Policy: + - strict-origin-when-cross-origin + Transfer-Encoding: + - chunked + Vary: + - Accept, Origin + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - dabc80c7-dd61-4690-97b3-a90194c235e6 + X-Runtime: + - '0.015330' X-XSS-Protection: - 1; mode=block status: diff --git a/tests/test_create_app.py b/tests/test_create_app.py index 08538ce..8a7ea62 100644 --- a/tests/test_create_app.py +++ b/tests/test_create_app.py @@ -66,4 +66,9 @@ def test_app_account_create(): ) test_token = test_app_api.create_account("coolguy" + suffix, "swordfish", "email@localhost" + suffix, agreement=True) assert test_token - + + # We can also test resending (marginally) + test_app_api.email_resend_confirmation() + + +