supython 0.1.15__tar.gz → 0.1.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. {supython-0.1.15 → supython-0.1.16}/CHANGELOG.md +19 -0
  2. {supython-0.1.15 → supython-0.1.16}/PKG-INFO +1 -1
  3. {supython-0.1.15 → supython-0.1.16}/pyproject.toml +1 -1
  4. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/router.py +134 -16
  5. {supython-0.1.15 → supython-0.1.16}/.gitignore +0 -0
  6. {supython-0.1.15 → supython-0.1.16}/LICENSE +0 -0
  7. {supython-0.1.15 → supython-0.1.16}/README.md +0 -0
  8. {supython-0.1.15 → supython-0.1.16}/SECURITY.md +0 -0
  9. {supython-0.1.15 → supython-0.1.16}/src/supython/__init__.py +0 -0
  10. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/__init__.py +0 -0
  11. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/__init__.py +0 -0
  12. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/auth.py +0 -0
  13. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/auth_templates.py +0 -0
  14. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/auth_users.py +0 -0
  15. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/db.py +0 -0
  16. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/functions.py +0 -0
  17. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/jobs.py +0 -0
  18. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/ops.py +0 -0
  19. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/realtime.py +0 -0
  20. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_auth.py +0 -0
  21. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_auth_templates.py +0 -0
  22. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_auth_users.py +0 -0
  23. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_db.py +0 -0
  24. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_functions.py +0 -0
  25. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_jobs.py +0 -0
  26. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_ops.py +0 -0
  27. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_realtime.py +0 -0
  28. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/service_storage.py +0 -0
  29. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/storage.py +0 -0
  30. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/api/system.py +0 -0
  31. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/audit.py +0 -0
  32. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/deps.py +0 -0
  33. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/errors.py +0 -0
  34. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/schemas.py +0 -0
  35. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/session.py +0 -0
  36. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/spa.py +0 -0
  37. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Alert-dluGVkos.js +0 -0
  38. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Alert-dluGVkos.js.map +0 -0
  39. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Audit-Njung3HI.js +0 -0
  40. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Audit-Njung3HI.js.map +0 -0
  41. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Backups-DzPlFgrm.js +0 -0
  42. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Backups-DzPlFgrm.js.map +0 -0
  43. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Buckets-ByacGkU1.js +0 -0
  44. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Buckets-ByacGkU1.js.map +0 -0
  45. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Channels-BoIuTtam.js +0 -0
  46. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Channels-BoIuTtam.js.map +0 -0
  47. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js +0 -0
  48. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/ChevronRight-CtQH1EQ1.js.map +0 -0
  49. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js +0 -0
  50. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/CodeViewer-Bqy7-wvH.js.map +0 -0
  51. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Crons-B67vc39F.js +0 -0
  52. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Crons-B67vc39F.js.map +0 -0
  53. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js +0 -0
  54. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/DashboardView-CUTFVL6k.js.map +0 -0
  55. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/DataTable-COAAWEft.js +0 -0
  56. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/DataTable-COAAWEft.js.map +0 -0
  57. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js +0 -0
  58. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/DescriptionsItem-P8JUDaBs.js.map +0 -0
  59. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js +0 -0
  60. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/DrawerContent-TpYTFgF1.js.map +0 -0
  61. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Empty-cr2r7e2u.js +0 -0
  62. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Empty-cr2r7e2u.js.map +0 -0
  63. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/EmptyState-DeDck-OL.js +0 -0
  64. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/EmptyState-DeDck-OL.js.map +0 -0
  65. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Grid-hFkp9F4P.js +0 -0
  66. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Grid-hFkp9F4P.js.map +0 -0
  67. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Input-DppYTq9C.js +0 -0
  68. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Input-DppYTq9C.js.map +0 -0
  69. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Invoke-DW3Nveeh.js +0 -0
  70. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Invoke-DW3Nveeh.js.map +0 -0
  71. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/JsonField-DibyJgun.js +0 -0
  72. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/JsonField-DibyJgun.js.map +0 -0
  73. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/LoginView-BjLyE3Ds.css +0 -0
  74. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/LoginView-CoOjECT_.js +0 -0
  75. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/LoginView-CoOjECT_.js.map +0 -0
  76. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Logs-D9WYrnIT.js +0 -0
  77. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Logs-D9WYrnIT.js.map +0 -0
  78. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Logs-DS1XPa0h.css +0 -0
  79. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js +0 -0
  80. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Migrations-DOSC2ddQ.js.map +0 -0
  81. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js +0 -0
  82. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/ObjectBrowser-_5w8vOX8.js.map +0 -0
  83. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Queue-CywZs6vI.js +0 -0
  84. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Queue-CywZs6vI.js.map +0 -0
  85. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js +0 -0
  86. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/RefreshTokens-Ccjr53jg.js.map +0 -0
  87. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js +0 -0
  88. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/RlsEditor-BSlH9vSc.js.map +0 -0
  89. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Routes-BiLXE49D.js +0 -0
  90. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Routes-BiLXE49D.js.map +0 -0
  91. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Routes-C-ianIGD.css +0 -0
  92. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/SchemaBrowser-DKy2_KQi.css +0 -0
  93. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js +0 -0
  94. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/SchemaBrowser-XFvFbtDB.js.map +0 -0
  95. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Select-DIzZyRZb.js +0 -0
  96. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Select-DIzZyRZb.js.map +0 -0
  97. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Space-n5-XcguU.js +0 -0
  98. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Space-n5-XcguU.js.map +0 -0
  99. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js +0 -0
  100. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/SqlEditor-b8pTsILY.js.map +0 -0
  101. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js +0 -0
  102. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/SqlWorkspace-BUS7IntH.js.map +0 -0
  103. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/TableData-CQIagLKn.js +0 -0
  104. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/TableData-CQIagLKn.js.map +0 -0
  105. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Tag-D1fOKpTH.js +0 -0
  106. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Tag-D1fOKpTH.js.map +0 -0
  107. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Templates-BS-ugkdq.js +0 -0
  108. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Templates-BS-ugkdq.js.map +0 -0
  109. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Thing-CEAniuMg.js +0 -0
  110. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Thing-CEAniuMg.js.map +0 -0
  111. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Users-wzwajhlh.js +0 -0
  112. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/Users-wzwajhlh.js.map +0 -0
  113. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/_plugin-vue_export-helper-DGA9ry_j.js +0 -0
  114. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/dist-VXIJLCYq.js +0 -0
  115. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/dist-VXIJLCYq.js.map +0 -0
  116. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/format-length-CGCY1rMh.js +0 -0
  117. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/format-length-CGCY1rMh.js.map +0 -0
  118. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/get-Ca6unauB.js +0 -0
  119. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/get-Ca6unauB.js.map +0 -0
  120. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/index-CeE6v959.js +0 -0
  121. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/index-CeE6v959.js.map +0 -0
  122. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/pinia-COXwfrOX.js +0 -0
  123. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/pinia-COXwfrOX.js.map +0 -0
  124. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/resources-Bt6thQCD.js +0 -0
  125. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/resources-Bt6thQCD.js.map +0 -0
  126. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/use-locale-mtgM0a3a.js +0 -0
  127. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/use-locale-mtgM0a3a.js.map +0 -0
  128. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js +0 -0
  129. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/use-merged-state-BvhkaHNX.js.map +0 -0
  130. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js +0 -0
  131. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useConfirm-tMjvBFXR.js.map +0 -0
  132. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useResource-C_rJCY8C.js +0 -0
  133. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useResource-C_rJCY8C.js.map +0 -0
  134. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useTable-CnZc5zhi.js +0 -0
  135. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useTable-CnZc5zhi.js.map +0 -0
  136. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useTable-Dg0XlRlq.css +0 -0
  137. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useToast-DsZKx0IX.js +0 -0
  138. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/useToast-DsZKx0IX.js.map +0 -0
  139. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/utils-sbXoq7Ir.js +0 -0
  140. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/assets/utils-sbXoq7Ir.js.map +0 -0
  141. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/favicon.svg +0 -0
  142. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/icons.svg +0 -0
  143. {supython-0.1.15 → supython-0.1.16}/src/supython/admin/static/index.html +0 -0
  144. {supython-0.1.15 → supython-0.1.16}/src/supython/app.py +0 -0
  145. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/__init__.py +0 -0
  146. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/_email_job.py +0 -0
  147. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/claims.py +0 -0
  148. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/deps.py +0 -0
  149. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/providers/__init__.py +0 -0
  150. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/providers/github.py +0 -0
  151. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/providers/google.py +0 -0
  152. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/providers/oauth.py +0 -0
  153. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/providers/registry.py +0 -0
  154. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/ratelimit.py +0 -0
  155. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/schemas.py +0 -0
  156. {supython-0.1.15 → supython-0.1.16}/src/supython/auth/service.py +0 -0
  157. {supython-0.1.15 → supython-0.1.16}/src/supython/backups/__init__.py +0 -0
  158. {supython-0.1.15 → supython-0.1.16}/src/supython/backups/_backup_job.py +0 -0
  159. {supython-0.1.15 → supython-0.1.16}/src/supython/backups/schemas.py +0 -0
  160. {supython-0.1.15 → supython-0.1.16}/src/supython/backups/service.py +0 -0
  161. {supython-0.1.15 → supython-0.1.16}/src/supython/body_size.py +0 -0
  162. {supython-0.1.15 → supython-0.1.16}/src/supython/cli.py +0 -0
  163. {supython-0.1.15 → supython-0.1.16}/src/supython/client/__init__.py +0 -0
  164. {supython-0.1.15 → supython-0.1.16}/src/supython/client/_auth.py +0 -0
  165. {supython-0.1.15 → supython-0.1.16}/src/supython/client/_client.py +0 -0
  166. {supython-0.1.15 → supython-0.1.16}/src/supython/client/_config.py +0 -0
  167. {supython-0.1.15 → supython-0.1.16}/src/supython/client/_functions.py +0 -0
  168. {supython-0.1.15 → supython-0.1.16}/src/supython/client/_storage.py +0 -0
  169. {supython-0.1.15 → supython-0.1.16}/src/supython/client/py.typed +0 -0
  170. {supython-0.1.15 → supython-0.1.16}/src/supython/db.py +0 -0
  171. {supython-0.1.15 → supython-0.1.16}/src/supython/db_admin.py +0 -0
  172. {supython-0.1.15 → supython-0.1.16}/src/supython/extensions.py +0 -0
  173. {supython-0.1.15 → supython-0.1.16}/src/supython/functions/__init__.py +0 -0
  174. {supython-0.1.15 → supython-0.1.16}/src/supython/functions/context.py +0 -0
  175. {supython-0.1.15 → supython-0.1.16}/src/supython/functions/loader.py +0 -0
  176. {supython-0.1.15 → supython-0.1.16}/src/supython/functions/router.py +0 -0
  177. {supython-0.1.15 → supython-0.1.16}/src/supython/functions/schemas.py +0 -0
  178. {supython-0.1.15 → supython-0.1.16}/src/supython/gen/__init__.py +0 -0
  179. {supython-0.1.15 → supython-0.1.16}/src/supython/gen/_introspect.py +0 -0
  180. {supython-0.1.15 → supython-0.1.16}/src/supython/gen/types_py.py +0 -0
  181. {supython-0.1.15 → supython-0.1.16}/src/supython/gen/types_ts.py +0 -0
  182. {supython-0.1.15 → supython-0.1.16}/src/supython/health.py +0 -0
  183. {supython-0.1.15 → supython-0.1.16}/src/supython/hooks.py +0 -0
  184. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/__init__.py +0 -0
  185. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/backends.py +0 -0
  186. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/context.py +0 -0
  187. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/cron.py +0 -0
  188. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/cron_inproc.py +0 -0
  189. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/decorators.py +0 -0
  190. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/registry.py +0 -0
  191. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/router.py +0 -0
  192. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/schemas.py +0 -0
  193. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/service.py +0 -0
  194. {supython-0.1.15 → supython-0.1.16}/src/supython/jobs/worker.py +0 -0
  195. {supython-0.1.15 → supython-0.1.16}/src/supython/jwks.py +0 -0
  196. {supython-0.1.15 → supython-0.1.16}/src/supython/keyset.py +0 -0
  197. {supython-0.1.15 → supython-0.1.16}/src/supython/logging_config.py +0 -0
  198. {supython-0.1.15 → supython-0.1.16}/src/supython/mail.py +0 -0
  199. {supython-0.1.15 → supython-0.1.16}/src/supython/mailer.py +0 -0
  200. {supython-0.1.15 → supython-0.1.16}/src/supython/migrate.py +0 -0
  201. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0001_extensions_and_roles.sql +0 -0
  202. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0002_auth_schema.sql +0 -0
  203. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0004_auth_v0_2.sql +0 -0
  204. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0005_storage_schema.sql +0 -0
  205. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0006_realtime_schema.sql +0 -0
  206. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0007_jobs_schema.sql +0 -0
  207. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0008_jobs_last_error.sql +0 -0
  208. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0009_auth_rate_limits.sql +0 -0
  209. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0010_worker_heartbeat.sql +0 -0
  210. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0011_admin_schema.sql +0 -0
  211. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0012_auth_banned_until.sql +0 -0
  212. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0013_email_templates.sql +0 -0
  213. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0014_realtime_payload_warning.sql +0 -0
  214. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0015_backups_schema.sql +0 -0
  215. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0016_magic_link_redirect.sql +0 -0
  216. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0017_auth_activated_at.sql +0 -0
  217. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0018_auth_email_confirmation.sql +0 -0
  218. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0019_hash_refresh_tokens.sql +0 -0
  219. {supython-0.1.15 → supython-0.1.16}/src/supython/migrations/0020_email_change_and_metadata.sql +0 -0
  220. {supython-0.1.15 → supython-0.1.16}/src/supython/netutil.py +0 -0
  221. {supython-0.1.15 → supython-0.1.16}/src/supython/passwords.py +0 -0
  222. {supython-0.1.15 → supython-0.1.16}/src/supython/realtime/__init__.py +0 -0
  223. {supython-0.1.15 → supython-0.1.16}/src/supython/realtime/broker.py +0 -0
  224. {supython-0.1.15 → supython-0.1.16}/src/supython/realtime/protocol.py +0 -0
  225. {supython-0.1.15 → supython-0.1.16}/src/supython/realtime/router.py +0 -0
  226. {supython-0.1.15 → supython-0.1.16}/src/supython/realtime/schemas.py +0 -0
  227. {supython-0.1.15 → supython-0.1.16}/src/supython/realtime/service.py +0 -0
  228. {supython-0.1.15 → supython-0.1.16}/src/supython/realtime/topics.py +0 -0
  229. {supython-0.1.15 → supython-0.1.16}/src/supython/realtime/websocket.py +0 -0
  230. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/__init__.py +0 -0
  231. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/init_project.py +0 -0
  232. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/Caddyfile.tmpl +0 -0
  233. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/README.md.tmpl +0 -0
  234. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/apps_hooks_welcome.py.tmpl +0 -0
  235. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/apps_jobs_example.py.tmpl +0 -0
  236. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/asgi.py.tmpl +0 -0
  237. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/docker-compose.prod.yml.tmpl +0 -0
  238. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/docker-compose.yml.tmpl +0 -0
  239. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/docker_postgres_Dockerfile.tmpl +0 -0
  240. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/docker_postgres_postgresql.conf.tmpl +0 -0
  241. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/env.example.tmpl +0 -0
  242. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/functions_README.md.tmpl +0 -0
  243. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/gitignore.tmpl +0 -0
  244. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/manage.py.tmpl +0 -0
  245. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/package_hooks_init.py.tmpl +0 -0
  246. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/package_init.py.tmpl +0 -0
  247. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/package_jobs_init.py.tmpl +0 -0
  248. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/pyproject.toml.tmpl +0 -0
  249. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/settings.py.tmpl +0 -0
  250. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/static/0001_create_todos.sql +0 -0
  251. {supython-0.1.15 → supython-0.1.16}/src/supython/scaffold/templates/static/functions_hello.py +0 -0
  252. {supython-0.1.15 → supython-0.1.16}/src/supython/secretset.py +0 -0
  253. {supython-0.1.15 → supython-0.1.16}/src/supython/security_headers.py +0 -0
  254. {supython-0.1.15 → supython-0.1.16}/src/supython/settings.py +0 -0
  255. {supython-0.1.15 → supython-0.1.16}/src/supython/settings_module.py +0 -0
  256. {supython-0.1.15 → supython-0.1.16}/src/supython/storage/__init__.py +0 -0
  257. {supython-0.1.15 → supython-0.1.16}/src/supython/storage/backends.py +0 -0
  258. {supython-0.1.15 → supython-0.1.16}/src/supython/storage/router.py +0 -0
  259. {supython-0.1.15 → supython-0.1.16}/src/supython/storage/schemas.py +0 -0
  260. {supython-0.1.15 → supython-0.1.16}/src/supython/storage/service.py +0 -0
  261. {supython-0.1.15 → supython-0.1.16}/src/supython/storage/signing.py +0 -0
  262. {supython-0.1.15 → supython-0.1.16}/src/supython/tokens.py +0 -0
@@ -30,6 +30,25 @@ Each entry links the relevant `PROJECT.md` section and decision-log row
30
30
 
31
31
  ---
32
32
 
33
+ ## [0.1.16] — 2026-07-22
34
+
35
+ ### Fixed
36
+ - Emailed-link interstitials (`GET /auth/v1/{confirm,magiclink,email_change}/verify`)
37
+ are usable in a browser again. The global CSP's `form-action 'none'`
38
+ blocked the form's self-POST that consumes the one-time token, so
39
+ clicking Confirm silently did nothing (#13). These responses now carry
40
+ their own scoped `Content-Security-Policy`
41
+ (`form-action 'self'; style-src 'unsafe-inline'`, still no `script-src`),
42
+ which the security-headers middleware yields to.
43
+
44
+ ### Changed
45
+ - Restyled the verify interstitials and the invalid-link page: a
46
+ dark-mode-aware card with inline SVG status icons, replacing the
47
+ previous bare unstyled markup. Still fully self-contained (system
48
+ fonts, no external requests) to stay within the scoped CSP.
49
+
50
+ ---
51
+
33
52
  ## [0.1.15] — 2026-07-21
34
53
 
35
54
  Auth hardening from the GHSA security review (three stacked PRs, #10–#12).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supython
3
- Version: 0.1.15
3
+ Version: 0.1.16
4
4
  Summary: A lightweight Postgres-first BaaS framework for Python
5
5
  Project-URL: Homepage, https://github.com/Tkeby/supython
6
6
  Project-URL: Repository, https://github.com/Tkeby/supython
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "supython"
7
- version = "0.1.15"
7
+ version = "0.1.16"
8
8
  description = "A lightweight Postgres-first BaaS framework for Python"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -100,7 +100,102 @@ def _client_ip_or_none(request: Request) -> str | None:
100
100
  )
101
101
 
102
102
 
103
- def _token_page(action_path: str, token: str, heading: str, button: str) -> HTMLResponse:
103
+ # Scoped CSP for the emailed-link interstitial pages. Unlike the global
104
+ # form-action 'none' policy, this permits the self-POST that consumes the token
105
+ # and the static inline <style>, while still forbidding all scripts.
106
+ _INTERSTITIAL_CSP = (
107
+ "default-src 'none'; style-src 'unsafe-inline'; "
108
+ "form-action 'self'; base-uri 'none'; frame-ancestors 'none'"
109
+ )
110
+
111
+
112
+ # All styling is inline in a single <style> block — the scoped CSP allows
113
+ # 'unsafe-inline' for style but forbids scripts and every external resource
114
+ # (no web fonts, no images), so the page must be self-contained: system fonts,
115
+ # inline SVG icons, and prefers-color-scheme for dark mode.
116
+ _PAGE_STYLE = """
117
+ *{box-sizing:border-box}
118
+ :root{
119
+ --bg1:#eef2ff;--bg2:#faf5ff;--card:#ffffff;--fg:#0f172a;--muted:#64748b;
120
+ --border:#e2e8f0;--accent:#4f46e5;--accent-hover:#4338ca;--icon-bg:#eef2ff;
121
+ --icon-fg:#4f46e5;--ring:rgba(79,70,229,.35)
122
+ }
123
+ @media (prefers-color-scheme:dark){
124
+ :root{
125
+ --bg1:#0b1120;--bg2:#0f172a;--card:#111827;--fg:#f1f5f9;--muted:#94a3b8;
126
+ --border:#1f2937;--accent:#6366f1;--accent-hover:#818cf8;--icon-bg:#1e253b;
127
+ --icon-fg:#a5b4fc;--ring:rgba(129,140,248,.4)
128
+ }
129
+ }
130
+ html,body{height:100%}
131
+ body{
132
+ margin:0;min-height:100%;
133
+ font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
134
+ color:var(--fg);
135
+ background:radial-gradient(1200px 600px at 50% -10%,var(--bg2),var(--bg1));
136
+ display:flex;align-items:center;justify-content:center;padding:24px
137
+ }
138
+ .card{
139
+ width:100%;max-width:420px;background:var(--card);
140
+ border:1px solid var(--border);border-radius:16px;
141
+ padding:40px 32px;text-align:center;
142
+ box-shadow:0 10px 30px -12px rgba(2,6,23,.25),0 4px 8px -4px rgba(2,6,23,.1)
143
+ }
144
+ .icon{
145
+ width:64px;height:64px;margin:0 auto 24px;border-radius:50%;
146
+ background:var(--icon-bg);color:var(--icon-fg);
147
+ display:flex;align-items:center;justify-content:center
148
+ }
149
+ .icon svg{width:32px;height:32px}
150
+ h1{font-size:1.4rem;line-height:1.3;margin:0 0 8px;font-weight:650}
151
+ p{margin:0 auto;max-width:32ch;color:var(--muted);font-size:.95rem;line-height:1.5}
152
+ form{margin:28px 0 0}
153
+ button{
154
+ -webkit-appearance:none;appearance:none;cursor:pointer;
155
+ width:100%;font-size:1rem;font-weight:600;
156
+ padding:.8rem 1.4rem;border:0;border-radius:10px;
157
+ color:#fff;background:var(--accent);transition:background .15s ease
158
+ }
159
+ button:hover{background:var(--accent-hover)}
160
+ button:focus-visible{outline:none;box-shadow:0 0 0 4px var(--ring)}
161
+ button:active{transform:translateY(1px)}
162
+ .footnote{margin-top:20px;font-size:.8rem;color:var(--muted)}
163
+ """
164
+
165
+ _CHECK_ICON = (
166
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" '
167
+ 'stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">'
168
+ '<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="M22 4 12 14.01l-3-3"/></svg>'
169
+ )
170
+ _WARN_ICON = (
171
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" '
172
+ 'stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">'
173
+ '<path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86'
174
+ 'a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/>'
175
+ '<line x1="12" y1="17" x2="12.01" y2="17"/></svg>'
176
+ )
177
+
178
+
179
+ def _shell(title: str, icon: str, body: str) -> str:
180
+ return f"""<!doctype html>
181
+ <html lang="en"><head><meta charset="utf-8">
182
+ <meta name="viewport" content="width=device-width, initial-scale=1">
183
+ <meta name="color-scheme" content="light dark">
184
+ <title>{title}</title>
185
+ <style>{_PAGE_STYLE}</style>
186
+ </head><body><main class="card">
187
+ <div class="icon">{icon}</div>
188
+ {body}
189
+ </main></body></html>"""
190
+
191
+
192
+ def _token_page(
193
+ action_path: str,
194
+ token: str,
195
+ heading: str,
196
+ button: str,
197
+ subtitle: str,
198
+ ) -> HTMLResponse:
104
199
  """Interstitial for emailed verify links.
105
200
 
106
201
  The emailed GET must stay side-effect-free — mail scanners prefetch GETs
@@ -108,25 +203,36 @@ def _token_page(action_path: str, token: str, heading: str, button: str) -> HTML
108
203
  Consumption happens on the form POST below, which scanners don't submit.
109
204
  The token rides in the form action's query string so no body parsing
110
205
  (python-multipart) is needed.
206
+
207
+ The global CSP (form-action 'none') would block the self-POST that consumes
208
+ the token, so this response carries its own scoped CSP (_INTERSTITIAL_CSP):
209
+ still no scripts, but the form may post to itself and the inline styles
210
+ apply. The markup has no user-injected content (heading/button/subtitle are
211
+ static; token is quote()-encoded into the action), so 'unsafe-inline' for
212
+ style is safe. The middleware yields to any pre-set CSP header.
111
213
  """
112
214
  action = f"{action_path}?token={quote(token, safe='')}"
113
- html = f"""<!doctype html>
114
- <html><head><meta charset="utf-8"><title>{heading}</title>
115
- <meta name="viewport" content="width=device-width, initial-scale=1">
116
- <style>body{{font-family:system-ui,sans-serif;display:flex;justify-content:center;padding-top:15vh;margin:0}}
117
- form{{text-align:center}}button{{font-size:1rem;padding:.6rem 1.4rem;cursor:pointer}}</style>
118
- </head><body><form method="post" action="{action}">
119
- <h1>{heading}</h1><button type="submit">{button}</button>
120
- </form></body></html>"""
121
- return HTMLResponse(html)
215
+ body = (
216
+ f"<h1>{heading}</h1><p>{subtitle}</p>"
217
+ f'<form method="post" action="{action}">'
218
+ f'<button type="submit">{button}</button></form>'
219
+ '<div class="footnote">This link can only be used once.</div>'
220
+ )
221
+ html = _shell(heading, _CHECK_ICON, body)
222
+ return HTMLResponse(html, headers={"content-security-policy": _INTERSTITIAL_CSP})
122
223
 
123
224
 
124
225
  def _invalid_link_page() -> HTMLResponse:
226
+ body = (
227
+ "<h1>Link invalid or expired</h1>"
228
+ "<p>This link may have already been used or timed out. "
229
+ "Request a new one and try again.</p>"
230
+ )
231
+ html = _shell("Link invalid or expired", _WARN_ICON, body)
125
232
  return HTMLResponse(
126
- "<!doctype html><html><body style=\"font-family:system-ui,sans-serif;"
127
- "text-align:center;padding-top:15vh\"><h1>Link invalid or expired</h1>"
128
- "<p>Request a new one and try again.</p></body></html>",
233
+ html,
129
234
  status_code=400,
235
+ headers={"content-security-policy": _INTERSTITIAL_CSP},
130
236
  )
131
237
 
132
238
 
@@ -403,7 +509,11 @@ async def magic_link_page(
403
509
  if not alive:
404
510
  return _invalid_link_page()
405
511
  return _token_page(
406
- "/auth/v1/magiclink/verify", token, "Sign in", "Continue"
512
+ "/auth/v1/magiclink/verify",
513
+ token,
514
+ "Sign in",
515
+ "Continue",
516
+ "Click below to finish signing in to your account.",
407
517
  )
408
518
 
409
519
 
@@ -455,7 +565,11 @@ async def signup_confirm_page(
455
565
  if not alive:
456
566
  return _invalid_link_page()
457
567
  return _token_page(
458
- "/auth/v1/confirm/verify", token, "Confirm your email", "Confirm"
568
+ "/auth/v1/confirm/verify",
569
+ token,
570
+ "Confirm your email",
571
+ "Confirm",
572
+ "Confirm your email address to activate your account.",
459
573
  )
460
574
 
461
575
 
@@ -527,7 +641,11 @@ async def email_change_page(
527
641
  if not alive:
528
642
  return _invalid_link_page()
529
643
  return _token_page(
530
- "/auth/v1/email_change/verify", token, "Confirm email change", "Confirm"
644
+ "/auth/v1/email_change/verify",
645
+ token,
646
+ "Confirm email change",
647
+ "Confirm",
648
+ "Confirm this address to complete your email change.",
531
649
  )
532
650
 
533
651
 
File without changes
File without changes
File without changes
File without changes
File without changes