railties 7.2.1.2 → 8.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +111 -297
- data/lib/minitest/rails_plugin.rb +1 -1
- data/lib/rails/application/configuration.rb +15 -2
- data/lib/rails/application/default_middleware_stack.rb +4 -0
- data/lib/rails/application/finisher.rb +2 -2
- data/lib/rails/application/routes_reloader.rb +11 -1
- data/lib/rails/application.rb +5 -0
- data/lib/rails/code_statistics.rb +128 -86
- data/lib/rails/code_statistics_calculator.rb +78 -76
- data/lib/rails/command/helpers/editor.rb +1 -1
- data/lib/rails/commands/app/update_command.rb +1 -9
- data/lib/rails/commands/credentials/USAGE +4 -4
- data/lib/rails/commands/credentials/credentials_command.rb +5 -1
- data/lib/rails/commands/dev/dev_command.rb +1 -1
- data/lib/rails/commands/devcontainer/devcontainer_command.rb +1 -1
- data/lib/rails/commands/stats/stats_command.rb +19 -0
- data/lib/rails/dev_caching.rb +2 -2
- data/lib/rails/engine/configuration.rb +3 -1
- data/lib/rails/engine/lazy_route_set.rb +109 -0
- data/lib/rails/engine.rb +10 -5
- data/lib/rails/gem_version.rb +4 -4
- data/lib/rails/generators/app_base.rb +46 -24
- data/lib/rails/generators/database.rb +101 -67
- data/lib/rails/generators/erb/authentication/authentication_generator.rb +15 -0
- data/lib/rails/generators/erb/authentication/templates/views/passwords/edit.html.erb +9 -0
- data/lib/rails/generators/erb/authentication/templates/views/passwords/new.html.erb +8 -0
- data/lib/rails/generators/erb/authentication/templates/views/sessions/new.html.erb +11 -0
- data/lib/rails/generators/generated_attribute.rb +16 -11
- data/lib/rails/generators/rails/app/app_generator.rb +19 -32
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +12 -3
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +23 -8
- data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt +6 -11
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +10 -3
- data/lib/rails/generators/rails/app/templates/bin/dev.tt +1 -0
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +5 -7
- data/lib/rails/generators/rails/app/templates/bin/thrust.tt +4 -0
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +23 -0
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +23 -0
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +40 -0
- data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +23 -0
- data/lib/rails/generators/rails/app/templates/config/deploy.yml.tt +124 -0
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -23
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +34 -51
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +5 -19
- data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +0 -7
- data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_8_0.rb.tt +25 -0
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +11 -2
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +3 -3
- data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +4 -3
- data/lib/rails/generators/rails/app/templates/dockerignore.tt +1 -2
- data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +1 -1
- data/lib/rails/generators/rails/app/templates/gitignore.tt +1 -2
- data/lib/rails/generators/rails/app/templates/kamal-secrets.tt +17 -0
- data/lib/rails/generators/rails/app/templates/public/400.html +114 -0
- data/lib/rails/generators/rails/app/templates/public/404.html +113 -66
- data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +113 -65
- data/lib/rails/generators/rails/app/templates/public/422.html +113 -66
- data/lib/rails/generators/rails/app/templates/public/500.html +113 -65
- data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
- data/lib/rails/generators/rails/app/templates/public/icon.svg +2 -2
- data/lib/rails/generators/rails/authentication/USAGE +6 -0
- data/lib/rails/generators/rails/authentication/authentication_generator.rb +54 -0
- data/lib/rails/generators/rails/authentication/templates/controllers/concerns/authentication.rb +55 -0
- data/lib/rails/generators/rails/authentication/templates/controllers/passwords_controller.rb +33 -0
- data/lib/rails/generators/rails/authentication/templates/controllers/sessions_controller.rb +21 -0
- data/lib/rails/generators/rails/authentication/templates/mailers/passwords_mailer.rb +6 -0
- data/lib/rails/generators/rails/authentication/templates/models/current.rb +4 -0
- data/lib/rails/generators/rails/authentication/templates/models/session.rb +3 -0
- data/lib/rails/generators/rails/authentication/templates/models/user.rb +6 -0
- data/lib/rails/generators/rails/authentication/templates/test/mailers/previews/passwords_mailer_preview.rb +7 -0
- data/lib/rails/generators/rails/authentication/templates/views/passwords_mailer/reset.html.erb +4 -0
- data/lib/rails/generators/rails/authentication/templates/views/passwords_mailer/reset.text.erb +2 -0
- data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +4 -0
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +1 -1
- data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +5 -3
- data/lib/rails/generators/rails/devcontainer/templates/devcontainer/devcontainer.json.tt +1 -1
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +11 -11
- data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +2 -2
- data/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt +2 -2
- data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt +3 -3
- data/lib/rails/generators/rails/script/USAGE +18 -0
- data/lib/rails/generators/rails/script/script_generator.rb +18 -0
- data/lib/rails/generators/rails/script/templates/script.rb.tt +3 -0
- data/lib/rails/generators.rb +7 -2
- data/lib/rails/info_controller.rb +10 -2
- data/lib/rails/rack/silence_request.rb +33 -0
- data/lib/rails/rack.rb +1 -0
- data/lib/rails/railtie.rb +13 -13
- data/lib/rails/source_annotation_extractor.rb +31 -14
- data/lib/rails/tasks/statistics.rake +13 -28
- data/lib/rails/templates/rails/info/notes.html.erb +65 -0
- metadata +41 -21
- data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -2
- data/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt +0 -4
- data/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt +0 -4
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +0 -70
- data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +0 -13
- data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +0 -13
- data/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt +0 -10
- data/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt +0 -6
- data/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt +0 -17
@@ -1,66 +1,114 @@
|
|
1
|
-
<!
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
<
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
1
|
+
<!doctype html>
|
2
|
+
|
3
|
+
<html lang="en">
|
4
|
+
|
5
|
+
<head>
|
6
|
+
|
7
|
+
<title>We’re sorry, but something went wrong (500 Internal Server Error)</title>
|
8
|
+
|
9
|
+
<meta charset="utf-8">
|
10
|
+
<meta name="viewport" content="initial-scale=1, width=device-width">
|
11
|
+
<meta name="robots" content="noindex, nofollow">
|
12
|
+
|
13
|
+
<style>
|
14
|
+
|
15
|
+
*, *::before, *::after {
|
16
|
+
box-sizing: border-box;
|
17
|
+
}
|
18
|
+
|
19
|
+
* {
|
20
|
+
margin: 0;
|
21
|
+
}
|
22
|
+
|
23
|
+
html {
|
24
|
+
font-size: 16px;
|
25
|
+
}
|
26
|
+
|
27
|
+
body {
|
28
|
+
background: #FFF;
|
29
|
+
color: #261B23;
|
30
|
+
display: grid;
|
31
|
+
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Aptos, Roboto, "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
32
|
+
font-size: clamp(1rem, 2.5vw, 2rem);
|
33
|
+
-webkit-font-smoothing: antialiased;
|
34
|
+
font-style: normal;
|
35
|
+
font-weight: 400;
|
36
|
+
letter-spacing: -0.0025em;
|
37
|
+
line-height: 1.4;
|
38
|
+
min-height: 100vh;
|
39
|
+
place-items: center;
|
40
|
+
text-rendering: optimizeLegibility;
|
41
|
+
-webkit-text-size-adjust: 100%;
|
42
|
+
}
|
43
|
+
|
44
|
+
a {
|
45
|
+
color: inherit;
|
46
|
+
font-weight: 700;
|
47
|
+
text-decoration: underline;
|
48
|
+
text-underline-offset: 0.0925em;
|
49
|
+
}
|
50
|
+
|
51
|
+
b, strong {
|
52
|
+
font-weight: 700;
|
53
|
+
}
|
54
|
+
|
55
|
+
i, em {
|
56
|
+
font-style: italic;
|
57
|
+
}
|
58
|
+
|
59
|
+
main {
|
60
|
+
display: grid;
|
61
|
+
gap: 1em;
|
62
|
+
padding: 2em;
|
63
|
+
place-items: center;
|
64
|
+
text-align: center;
|
65
|
+
}
|
66
|
+
|
67
|
+
main header {
|
68
|
+
width: min(100%, 12em);
|
69
|
+
}
|
70
|
+
|
71
|
+
main header svg {
|
72
|
+
height: auto;
|
73
|
+
max-width: 100%;
|
74
|
+
width: 100%;
|
75
|
+
}
|
76
|
+
|
77
|
+
main article {
|
78
|
+
width: min(100%, 30em);
|
79
|
+
}
|
80
|
+
|
81
|
+
main article p {
|
82
|
+
font-size: 75%;
|
83
|
+
}
|
84
|
+
|
85
|
+
main article br {
|
86
|
+
|
87
|
+
display: none;
|
88
|
+
|
89
|
+
@media(min-width: 48em) {
|
90
|
+
display: inline;
|
91
|
+
}
|
92
|
+
|
93
|
+
}
|
94
|
+
|
95
|
+
</style>
|
96
|
+
|
97
|
+
</head>
|
98
|
+
|
99
|
+
<body>
|
100
|
+
|
101
|
+
<!-- This file lives in public/500.html -->
|
102
|
+
|
103
|
+
<main>
|
104
|
+
<header>
|
105
|
+
<svg height="172" viewBox="0 0 480 172" width="480" xmlns="http://www.w3.org/2000/svg"><path d="m101.23 93.8427c-8.1103 0-15.4098 3.7849-19.7354 8.3813h-36.2269v-99.21891h103.8143v37.03791h-68.3984v24.8722c5.1366-2.7035 15.1396-5.9477 24.6014-5.9477 35.146 0 56.233 22.7094 56.233 55.4215 0 34.605-23.791 57.315-60.558 57.315-37.8492 0-61.64-22.169-63.8028-55.963h42.9857c1.0814 10.814 9.1919 19.195 21.6281 19.195 11.355 0 19.465-8.381 19.465-20.547 0-11.625-7.299-20.5463-20.006-20.5463zm138.833 77.8613c-40.822 0-64.884-35.146-64.884-85.7015 0-50.5554 24.062-85.700907 64.884-85.700907 40.823 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.061 85.7015-64.884 85.7015zm0-133.2831c-17.572 0-22.709 21.8984-22.709 47.5816 0 25.6835 5.137 47.5815 22.709 47.5815 17.303 0 22.71-21.898 22.71-47.5815 0-25.6832-5.407-47.5816-22.71-47.5816zm140.456 133.2831c-40.823 0-64.884-35.146-64.884-85.7015 0-50.5554 24.061-85.700907 64.884-85.700907 40.822 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.062 85.7015-64.884 85.7015zm0-133.2831c-17.573 0-22.71 21.8984-22.71 47.5816 0 25.6835 5.137 47.5815 22.71 47.5815 17.302 0 22.709-21.898 22.709-47.5815 0-25.6832-5.407-47.5816-22.709-47.5816z" fill="#f0eff0"/><path d="m23.1377 68.9967v34.0033h-8.9162v-34.0033zm4.3157 34.0033v-24.921h8.6947v2.1598c1.3845-1.5506 3.8212-2.7136 6.701-2.7136 5.538 0 8.8054 3.5997 8.8054 9.1377v16.3371h-8.6393v-14.2327c0-2.049-1.0522-3.5443-3.2674-3.5443-1.7168 0-3.1567.9969-3.5997 2.7136v15.0634zm29.9913-8.5839v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.5839v6.8671h5.2058v6.7564h-5.2058v8.307c0 1.9383.9415 2.769 2.6583 2.769.9414 0 1.9937-.2216 2.769-.5538v7.3654c-.9969.443-2.8798.775-4.8181.775-5.8703 0-9.1931-2.769-9.1931-9.0819zm32.3666-.1108h8.0301c-.8861 5.7597-5.2057 9.2487-11.6852 9.2487-7.6424 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.3165-13.0143 12.5159-13.0143 7.6424 0 11.9621 5.095 11.9621 12.5159v2.1598h-16.1156c.2769 2.9905 1.8275 4.5965 4.3196 4.5965 1.7722 0 3.1567-.7753 3.6551-2.4921zm-3.8212-10.0237c-2.0491 0-3.4336 1.2737-3.9874 3.5997h7.5317c-.1107-2.0491-1.3845-3.5997-3.5443-3.5997zm31.4299-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.599-.7753-2.382 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.381.443zm2.949 25.0318v-24.921h8.694v2.1598c1.385-1.5506 3.821-2.7136 6.701-2.7136 5.538 0 8.806 3.5997 8.806 9.1377v16.3371h-8.64v-14.2327c0-2.049-1.052-3.5443-3.267-3.5443-1.717 0-3.157.9969-3.6 2.7136v15.0634zm50.371 0h-8.363v-1.274c-.83.831-3.323 1.717-5.981 1.717-4.929 0-9.082-2.769-9.082-8.0301 0-4.818 4.153-7.9193 9.581-7.9193 2.049 0 4.485.6646 5.482 1.3845v-1.606c0-1.606-.941-2.9905-3.046-2.9905-1.606 0-2.547.7199-2.935 1.8275h-8.196c.72-4.8181 4.984-8.6393 11.408-8.6393 7.089 0 11.132 3.7659 11.132 10.2453zm-8.363-6.9779v-1.4399c-.554-1.0522-2.049-1.7167-3.655-1.7167-1.717 0-3.433.7199-3.433 2.3813 0 1.7168 1.716 2.4367 3.433 2.4367 1.606 0 3.101-.6645 3.655-1.6614zm20.742-29.0191v35.997h-8.694v-35.997zm13.036 25.9178h9.248c.72 2.326 2.714 3.489 5.483 3.489 2.713 0 4.596-1.163 4.596-3.2674 0-1.6061-1.052-2.326-3.212-2.8244l-6.534-1.3845c-4.985-1.1076-8.751-3.7105-8.751-9.47 0-6.6456 5.538-11.0206 13.07-11.0206 8.307 0 13.014 4.5411 13.956 10.4114h-8.695c-.72-1.8829-2.27-3.3228-5.205-3.3228-2.548 0-4.265 1.1076-4.265 2.9905 0 1.4953 1.052 2.326 2.825 2.7137l6.645 1.5506c5.815 1.3845 9.027 4.5412 9.027 9.8023 0 6.9778-5.87 10.9654-13.291 10.9654-8.141 0-13.679-3.9322-14.897-10.6332zm46.509 1.3845h8.031c-.887 5.7597-5.206 9.2487-11.686 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.317-13.0143 12.516-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.319 4.5965 1.773 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm31.431-6.3134v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.382.443zm18.288 25.0318h-7.809l-9.47-24.921h8.861l4.763 14.288 4.652-14.288h8.528zm25.614-8.6947h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.516-13.0143 7.642 0 11.962 5.095 11.962 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.434 1.2737-3.988 3.5997h7.532c-.111-2.0491-1.384-3.5997-3.544-3.5997zm31.43-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443zm13.703-8.9715h24.312v7.6424h-15.562v5.3165h14.232v7.4763h-14.232v5.8703h15.562v7.6978h-24.312zm44.667 8.9715v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm19.673 0v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm26.769 12.5713c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.529 0c0-3.4336-1.495-5.8703-4.208-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.208-2.3813 4.208-5.8149zm28.082-12.5713v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443z" fill="#d30001"/></svg>
|
106
|
+
</header>
|
107
|
+
<article>
|
108
|
+
<p><strong>We’re sorry, but something went wrong.</strong><br> If you’re the application owner check the logs for more information.</p>
|
109
|
+
</article>
|
110
|
+
</main>
|
111
|
+
|
112
|
+
</body>
|
113
|
+
|
66
114
|
</html>
|
Binary file
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<svg width="
|
2
|
-
<
|
1
|
+
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<circle cx="256" cy="256" r="256" fill="red"/>
|
3
3
|
</svg>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
module Generators
|
5
|
+
class AuthenticationGenerator < Base # :nodoc:
|
6
|
+
class_option :api, type: :boolean,
|
7
|
+
desc: "Generate API-only controllers and models, with no view templates"
|
8
|
+
|
9
|
+
hook_for :template_engine, as: :authentication do |template_engine|
|
10
|
+
invoke template_engine unless options.api?
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_authentication_files
|
14
|
+
template "models/session.rb", File.join("app/models/session.rb")
|
15
|
+
template "models/user.rb", File.join("app/models/user.rb")
|
16
|
+
template "models/current.rb", File.join("app/models/current.rb")
|
17
|
+
|
18
|
+
template "controllers/sessions_controller.rb", File.join("app/controllers/sessions_controller.rb")
|
19
|
+
template "controllers/concerns/authentication.rb", File.join("app/controllers/concerns/authentication.rb")
|
20
|
+
template "controllers/passwords_controller.rb", File.join("app/controllers/passwords_controller.rb")
|
21
|
+
|
22
|
+
template "mailers/passwords_mailer.rb", File.join("app/mailers/passwords_mailer.rb")
|
23
|
+
|
24
|
+
template "views/passwords_mailer/reset.html.erb", File.join("app/views/passwords_mailer/reset.html.erb")
|
25
|
+
template "views/passwords_mailer/reset.text.erb", File.join("app/views/passwords_mailer/reset.text.erb")
|
26
|
+
|
27
|
+
template "test/mailers/previews/passwords_mailer_preview.rb", File.join("test/mailers/previews/passwords_mailer_preview.rb")
|
28
|
+
end
|
29
|
+
|
30
|
+
def configure_application_controller
|
31
|
+
gsub_file "app/controllers/application_controller.rb", /(class ApplicationController < ActionController::Base)/, "\\1\n include Authentication"
|
32
|
+
end
|
33
|
+
|
34
|
+
def configure_authentication_routes
|
35
|
+
route "resources :passwords, param: :token"
|
36
|
+
route "resource :session"
|
37
|
+
end
|
38
|
+
|
39
|
+
def enable_bcrypt
|
40
|
+
if File.read("Gemfile").include?('gem "bcrypt"')
|
41
|
+
uncomment_lines "Gemfile", /gem "bcrypt"/
|
42
|
+
Bundler.with_original_env { execute_command :bundle, "install --quiet" }
|
43
|
+
else
|
44
|
+
Bundler.with_original_env { execute_command :bundle, "add bcrypt --quiet" }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_migrations
|
49
|
+
generate "migration CreateUsers email_address:string!:uniq password_digest:string! --force"
|
50
|
+
generate "migration CreateSessions user:references ip_address:string user_agent:string --force"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/rails/generators/rails/authentication/templates/controllers/concerns/authentication.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Authentication
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
before_action :require_authentication
|
6
|
+
helper_method :authenticated?
|
7
|
+
end
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
def allow_unauthenticated_access(**options)
|
11
|
+
skip_before_action :require_authentication, **options
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def authenticated?
|
17
|
+
Current.session.present?
|
18
|
+
end
|
19
|
+
|
20
|
+
def require_authentication
|
21
|
+
resume_session || request_authentication
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def resume_session
|
26
|
+
Current.session = find_session_by_cookie
|
27
|
+
end
|
28
|
+
|
29
|
+
def find_session_by_cookie
|
30
|
+
Session.find_by(id: cookies.signed[:session_id])
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def request_authentication
|
35
|
+
session[:return_to_after_authenticating] = request.url
|
36
|
+
redirect_to new_session_url
|
37
|
+
end
|
38
|
+
|
39
|
+
def after_authentication_url
|
40
|
+
session.delete(:return_to_after_authenticating) || root_url
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def start_new_session_for(user)
|
45
|
+
user.sessions.create!(user_agent: request.user_agent, ip_address: request.remote_ip).tap do |session|
|
46
|
+
Current.session = session
|
47
|
+
cookies.signed.permanent[:session_id] = { value: session.id, httponly: true, same_site: :lax }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def terminate_session
|
52
|
+
Current.session.destroy
|
53
|
+
cookies.delete(:session_id)
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class PasswordsController < ApplicationController
|
2
|
+
allow_unauthenticated_access
|
3
|
+
before_action :set_user_by_token, only: %i[ edit update ]
|
4
|
+
|
5
|
+
def new
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
if user = User.find_by(email_address: params[:email_address])
|
10
|
+
PasswordsMailer.reset(user).deliver_later
|
11
|
+
end
|
12
|
+
|
13
|
+
redirect_to new_session_url, notice: "Password reset instructions sent (if user with that email address exists)."
|
14
|
+
end
|
15
|
+
|
16
|
+
def edit
|
17
|
+
end
|
18
|
+
|
19
|
+
def update
|
20
|
+
if @user.update(params.permit(:password, :password_confirmation))
|
21
|
+
redirect_to new_session_url, notice: "Password has been reset."
|
22
|
+
else
|
23
|
+
redirect_to edit_password_url(params[:token]), alert: "Passwords did not match."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def set_user_by_token
|
29
|
+
@user = User.find_by_password_reset_token!(params[:token])
|
30
|
+
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
31
|
+
redirect_to new_password_url, alert: "Password reset link is invalid or has expired."
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class SessionsController < ApplicationController
|
2
|
+
allow_unauthenticated_access only: %i[ new create ]
|
3
|
+
rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_session_url, alert: "Try again later." }
|
4
|
+
|
5
|
+
def new
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
if user = User.authenticate_by(params.permit(:email_address, :password))
|
10
|
+
start_new_session_for user
|
11
|
+
redirect_to after_authentication_url
|
12
|
+
else
|
13
|
+
redirect_to new_session_url, alert: "Try another email address or password."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def destroy
|
18
|
+
terminate_session
|
19
|
+
redirect_to new_session_url
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Preview all emails at http://localhost:3000/rails/mailers/passwords_mailer
|
2
|
+
class PasswordsMailerPreview < ActionMailer::Preview
|
3
|
+
# Preview this email at http://localhost:3000/rails/mailers/passwords_mailer/reset
|
4
|
+
def reset
|
5
|
+
PasswordsMailer.reset(User.take)
|
6
|
+
end
|
7
|
+
end
|
@@ -38,9 +38,11 @@ module Rails
|
|
38
38
|
|
39
39
|
def update_application_system_test_case
|
40
40
|
return unless options[:system_test]
|
41
|
-
return unless File.exist?("test/application_system_test_case.rb")
|
42
41
|
|
43
|
-
|
42
|
+
system_test_case_path = File.expand_path "test/application_system_test_case.rb", destination_root
|
43
|
+
return unless File.exist? system_test_case_path
|
44
|
+
|
45
|
+
gsub_file(system_test_case_path, /^\s*driven_by\b.*/, system_test_configuration)
|
44
46
|
end
|
45
47
|
|
46
48
|
def update_database_yml
|
@@ -148,7 +150,7 @@ module Rails
|
|
148
150
|
end
|
149
151
|
|
150
152
|
def system_test_configuration
|
151
|
-
optimize_indentation(<<-'RUBY', 2)
|
153
|
+
optimize_indentation(<<-'RUBY', 2).chomp
|
152
154
|
if ENV["CAPYBARA_SERVER_PORT"]
|
153
155
|
served_by host: "rails-app", port: ENV["CAPYBARA_SERVER_PORT"]
|
154
156
|
|
@@ -122,9 +122,12 @@ module Rails
|
|
122
122
|
def generate_test_dummy(force = false)
|
123
123
|
opts = options.transform_keys(&:to_sym).except(*DUMMY_IGNORE_OPTIONS)
|
124
124
|
opts[:force] = force
|
125
|
+
opts[:skip_thruster] = true
|
125
126
|
opts[:skip_brakeman] = true
|
126
127
|
opts[:skip_bundle] = true
|
127
128
|
opts[:skip_ci] = true
|
129
|
+
opts[:skip_kamal] = true
|
130
|
+
opts[:skip_solid] = true
|
128
131
|
opts[:skip_git] = true
|
129
132
|
opts[:skip_hotwire] = true
|
130
133
|
opts[:skip_rubocop] = true
|
@@ -149,9 +152,8 @@ module Rails
|
|
149
152
|
end
|
150
153
|
end
|
151
154
|
|
152
|
-
def
|
153
|
-
template "rails/stylesheets.css",
|
154
|
-
template "rails/dummy_manifest.js", "#{dummy_path}/app/assets/config/manifest.js", force: true
|
155
|
+
def test_dummy_assets
|
156
|
+
template "rails/stylesheets.css", "#{dummy_path}/app/assets/stylesheets/application.css", force: true
|
155
157
|
end
|
156
158
|
|
157
159
|
def test_dummy_clean
|
@@ -159,7 +161,7 @@ module Rails
|
|
159
161
|
remove_file ".ruby-version"
|
160
162
|
remove_dir "db"
|
161
163
|
remove_file "Gemfile"
|
162
|
-
|
164
|
+
remove_dir "lib"
|
163
165
|
remove_file "public/robots.txt"
|
164
166
|
remove_file "README.md"
|
165
167
|
remove_file "test"
|
@@ -167,10 +169,6 @@ module Rails
|
|
167
169
|
end
|
168
170
|
end
|
169
171
|
|
170
|
-
def assets_manifest
|
171
|
-
template "rails/engine_manifest.js", "app/assets/config/#{underscored_name}_manifest.js"
|
172
|
-
end
|
173
|
-
|
174
172
|
def stylesheets
|
175
173
|
if mountable?
|
176
174
|
copy_file "rails/stylesheets.css",
|
@@ -361,7 +359,7 @@ module Rails
|
|
361
359
|
mute do
|
362
360
|
build(:generate_test_dummy)
|
363
361
|
build(:test_dummy_config)
|
364
|
-
build(:
|
362
|
+
build(:test_dummy_assets) unless skip_asset_pipeline?
|
365
363
|
build(:test_dummy_clean)
|
366
364
|
# ensure that bin/rails has proper dummy_path
|
367
365
|
build(:bin)
|
@@ -491,9 +489,11 @@ module Rails
|
|
491
489
|
|
492
490
|
def test_command
|
493
491
|
if engine? && !options[:skip_active_record] && with_dummy_app?
|
494
|
-
"db:test:prepare test"
|
492
|
+
"bin/rails db:test:prepare test"
|
493
|
+
elsif engine?
|
494
|
+
"bin/rails test"
|
495
495
|
else
|
496
|
-
"test"
|
496
|
+
"bin/test"
|
497
497
|
end
|
498
498
|
end
|
499
499
|
end
|
@@ -90,7 +90,7 @@ jobs:
|
|
90
90
|
DATABASE_URL: postgres://postgres:postgres@localhost:5432
|
91
91
|
<%- end -%>
|
92
92
|
# REDIS_URL: redis://localhost:6379/0
|
93
|
-
run:
|
93
|
+
run: <%= test_command %>
|
94
94
|
|
95
95
|
- name: Keep screenshots from failed system tests
|
96
96
|
uses: actions/upload-artifact@v4
|
@@ -3,7 +3,7 @@ ENV["RAILS_ENV"] = "test"
|
|
3
3
|
|
4
4
|
require_relative "<%= File.join("..", options[:dummy_path], "config/environment") -%>"
|
5
5
|
<% unless options[:skip_active_record] -%>
|
6
|
-
ActiveRecord::Migrator.migrations_paths = [File.expand_path("../<%= options[:dummy_path] -%>/db/migrate", __dir__)]
|
6
|
+
ActiveRecord::Migrator.migrations_paths = [ File.expand_path("../<%= options[:dummy_path] -%>/db/migrate", __dir__) ]
|
7
7
|
<% if options[:mountable] -%>
|
8
8
|
ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__)
|
9
9
|
<% end -%>
|
@@ -13,7 +13,7 @@ require "rails/test_help"
|
|
13
13
|
<% unless options[:skip_active_record] -%>
|
14
14
|
# Load fixtures from the engine
|
15
15
|
if ActiveSupport::TestCase.respond_to?(:fixture_paths=)
|
16
|
-
ActiveSupport::TestCase.fixture_paths = [File.expand_path("fixtures", __dir__)]
|
16
|
+
ActiveSupport::TestCase.fixture_paths = [ File.expand_path("fixtures", __dir__) ]
|
17
17
|
ActionDispatch::IntegrationTest.fixture_paths = ActiveSupport::TestCase.fixture_paths
|
18
18
|
ActiveSupport::TestCase.file_fixture_path = File.expand_path("fixtures", __dir__) + "/files"
|
19
19
|
ActiveSupport::TestCase.fixtures :all
|
@@ -42,7 +42,7 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
42
42
|
private
|
43
43
|
# Use callbacks to share common setup or constraints between actions.
|
44
44
|
def set_<%= singular_table_name %>
|
45
|
-
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params
|
45
|
+
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params.expect(:id)") %>
|
46
46
|
end
|
47
47
|
|
48
48
|
# Only allow a list of trusted parameters through.
|
@@ -50,7 +50,7 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
50
50
|
<%- if attributes_names.empty? -%>
|
51
51
|
params.fetch(:<%= singular_table_name %>, {})
|
52
52
|
<%- else -%>
|
53
|
-
params.
|
53
|
+
params.expect(<%= singular_table_name %>: [ <%= permitted_params %> ])
|
54
54
|
<%- end -%>
|
55
55
|
end
|
56
56
|
end
|
@@ -43,13 +43,13 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
43
43
|
# DELETE <%= route_url %>/1
|
44
44
|
def destroy
|
45
45
|
@<%= orm_instance.destroy %>
|
46
|
-
redirect_to <%= index_helper %>
|
46
|
+
redirect_to <%= index_helper %>_path, notice: <%= %("#{human_name} was successfully destroyed.") %>, status: :see_other
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
50
50
|
# Use callbacks to share common setup or constraints between actions.
|
51
51
|
def set_<%= singular_table_name %>
|
52
|
-
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params
|
52
|
+
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params.expect(:id)") %>
|
53
53
|
end
|
54
54
|
|
55
55
|
# Only allow a list of trusted parameters through.
|
@@ -57,7 +57,7 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
57
57
|
<%- if attributes_names.empty? -%>
|
58
58
|
params.fetch(:<%= singular_table_name %>, {})
|
59
59
|
<%- else -%>
|
60
|
-
params.
|
60
|
+
params.expect(<%= singular_table_name %>: [ <%= permitted_params %> ])
|
61
61
|
<%- end -%>
|
62
62
|
end
|
63
63
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Description:
|
2
|
+
Generate a one-off or general purpose script, such as a data migration
|
3
|
+
script, cleanup script, etc.
|
4
|
+
|
5
|
+
Example:
|
6
|
+
`bin/rails generate script my_script`
|
7
|
+
|
8
|
+
This will create:
|
9
|
+
script/my_script.rb
|
10
|
+
|
11
|
+
You can run the script using:
|
12
|
+
`ruby script/my_script.rb`
|
13
|
+
|
14
|
+
You can specify a folder:
|
15
|
+
`bin/rails generate script cleanup/my_script`
|
16
|
+
|
17
|
+
This will create:
|
18
|
+
script/cleanup/my_script.rb
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/named_base"
|
4
|
+
|
5
|
+
module Rails
|
6
|
+
module Generators
|
7
|
+
class ScriptGenerator < NamedBase
|
8
|
+
def generate_script
|
9
|
+
template("script.rb.tt", "script/#{file_path}.rb")
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def depth
|
14
|
+
class_path.size + 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|