├── .github
├── FUNDING.yml
└── workflows
│ └── update-kirby-submodule.yml
├── .gitmodules
├── site
├── templates
│ ├── emails
│ │ ├── account-activation.text.php
│ │ └── account-activation.html.php
│ ├── user.json.php
│ ├── user.csv.php
│ ├── login.php
│ ├── register.php
│ └── user.php
├── snippets
│ ├── notification.php
│ └── header.php
├── blueprints
│ ├── users
│ │ └── user.yml
│ └── pages
│ │ ├── login.yml
│ │ └── register.yml
├── controllers
│ ├── login.php
│ ├── register.php
│ └── user.php
└── config
│ └── config.php
├── content
├── site.txt
├── login
│ └── login.txt
├── register
│ └── register.txt
└── user
│ └── user.txt
├── ISSUE_TEMPLATE.md
├── .editorconfig
├── LICENSE
├── .gitignore
└── README.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: kreativ-anders
2 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "kirby"]
2 | path = kirby
3 | url = https://github.com/getkirby/kirby.git
4 |
--------------------------------------------------------------------------------
/site/templates/emails/account-activation.text.php:
--------------------------------------------------------------------------------
1 | Welcome,
2 |
3 | Please click the link to activate your Account: = $link ?>
--------------------------------------------------------------------------------
/site/templates/emails/account-activation.html.php:
--------------------------------------------------------------------------------
1 |
Welcome
2 | Please click the link to activate your Account: = $link ?>
--------------------------------------------------------------------------------
/site/snippets/notification.php:
--------------------------------------------------------------------------------
1 |
2 |
= isset($error) ? $page->alert()->html() : '' ?>
3 |
= isset($alert['error']) ? html($alert['error']) : '' ?>
4 |
5 |
--------------------------------------------------------------------------------
/content/site.txt:
--------------------------------------------------------------------------------
1 | Title: Mægazine
2 |
3 | ----
4 |
5 | Login: Login
6 |
7 | ----
8 |
9 | Logout: Logout
10 |
11 | ----
12 |
13 | Register: Register
14 |
15 | ----
16 |
17 | User: User Settings
18 |
--------------------------------------------------------------------------------
/content/login/login.txt:
--------------------------------------------------------------------------------
1 | Title: Login
2 |
3 | ----
4 |
5 | Alert: Invalid email or password
6 |
7 | ----
8 |
9 | Email: Email
10 |
11 | ----
12 |
13 | Password: Password
14 |
15 | ----
16 |
17 | Button: Login
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Expected Behavior
2 |
3 |
4 | ## Actual Behavior
5 |
6 |
7 | ## Steps to Reproduce the Problem
8 |
9 | 1.
10 | 1.
11 | 1.
12 |
13 | ## Idea
14 |
15 | Any ideas already how to solve it?
16 |
--------------------------------------------------------------------------------
/content/register/register.txt:
--------------------------------------------------------------------------------
1 | Title: Register
2 |
3 | ----
4 |
5 | Alert: Invalid email or password
6 |
7 | ----
8 |
9 | Honeypot: Username
10 |
11 | ----
12 |
13 | Email: Email
14 |
15 | ----
16 |
17 | Password: Password
18 |
19 | ----
20 |
21 | Button: Register
22 |
--------------------------------------------------------------------------------
/site/blueprints/users/user.yml:
--------------------------------------------------------------------------------
1 | title: User
2 |
3 | permissions:
4 | access:
5 | panel: false
6 |
7 | fields:
8 | info:
9 | label: Info
10 | type: info
11 | theme: passive
12 | text: "User was last modified on {{ user.modified('l, d. M Y — g:i a') }}"
--------------------------------------------------------------------------------
/site/templates/user.json.php:
--------------------------------------------------------------------------------
1 | user()) {
6 |
7 | $bookmarks = $kirby->user()->bookmarks()->yaml();
8 |
9 | $json = [
10 | 'User' => $kirby->user()->email()
11 | ];
12 |
13 | }
14 | else {
15 | $json = [];
16 | }
17 |
18 | echo json_encode($json);
--------------------------------------------------------------------------------
/site/blueprints/pages/login.yml:
--------------------------------------------------------------------------------
1 | title: Login
2 | icon: 🔐
3 |
4 | fields:
5 | alert:
6 | label: Alert text
7 | type: text
8 | email:
9 | label: Label for email
10 | type: email
11 | password:
12 | label: Label for password
13 | type: text
14 | button:
15 | label: Button text
16 | type: text
--------------------------------------------------------------------------------
/site/templates/user.csv.php:
--------------------------------------------------------------------------------
1 | user()) {
8 |
9 | $csv .= "Email;Langauge\n";
10 | $csv .= $kirby->user()->email().";".$kirby->user()->language()."\n";
11 |
12 |
13 | }
14 | else {
15 | $csv = [];
16 | }
17 |
18 | echo $csv;
--------------------------------------------------------------------------------
/site/blueprints/pages/register.yml:
--------------------------------------------------------------------------------
1 | title: Register
2 | icon: 🔐
3 |
4 | fields:
5 | alert:
6 | label: Alert text
7 | type: text
8 | email:
9 | label: Label for email
10 | type: email
11 | email_info:
12 | label: GDPR info for email
13 | type: text
14 | password:
15 | label: Label for password
16 | type: text
17 | password_info:
18 | label: GDPR info for password
19 | type: text
20 | button:
21 | label: Button text
22 | type: text
--------------------------------------------------------------------------------
/content/user/user.txt:
--------------------------------------------------------------------------------
1 | Title: User Settings
2 |
3 | ----
4 |
5 | Alert: Invalid email or password
6 |
7 | ----
8 |
9 | Email: New Email
10 |
11 | ----
12 |
13 | Password: New Password
14 |
15 | ----
16 |
17 | Button: Update User
18 |
19 | ----
20 |
21 | Export: Export and download YOUR data:
22 |
23 | ----
24 |
25 | Danger: Danger Zone
26 |
27 | ----
28 |
29 | Delete_Button: Delete Account
30 |
31 | ----
32 |
33 | Delete_Warning: Are you sure? This action cannot be reversed!
34 |
35 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{css,scss,less,js,json,ts,sass,html,hbs,mustache,phtml,html.twig,md,yml}]
2 | charset = utf-8
3 | indent_style = space
4 | indent_size = 2
5 | end_of_line = lf
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 |
9 | [*.md]
10 | indent_size = 4
11 | trim_trailing_whitespace = false
12 |
13 | [site/templates/**.php]
14 | indent_size = 2
15 |
16 | [site/snippets/**.php]
17 | indent_size = 2
18 |
19 | [package.json,.{babelrc,editorconfig,eslintrc,lintstagedrc,stylelintrc}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/site/templates/login.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
30 |
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 kreativ-anders | Manuel Steinberg
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/site/templates/register.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
36 |
37 |
--------------------------------------------------------------------------------
/site/controllers/login.php:
--------------------------------------------------------------------------------
1 | user()) {
6 | go('/');
7 | }
8 |
9 | $error = null;
10 | $alert = null;
11 |
12 | if ($kirby->request()->is('POST') && get('login')) {
13 |
14 | // VALIDATE CSRF TOKEN
15 | if (csrf(get('csrf')) === true) {
16 |
17 | // GET FORM DATA
18 | $data = [
19 | 'email' => get('email'),
20 | 'password' => get('password')
21 | ];
22 |
23 | $rules = [
24 | 'email' => ['required', 'email'],
25 | 'password' => ['required']
26 | ];
27 |
28 | $messages = [
29 | 'email' => 'Please enter a valid email adress',
30 | 'password' => 'Please enter a password'
31 | ];
32 |
33 | // VALIDATE FORM DATA
34 | if($invalid = invalid($data, $rules, $messages)) {
35 |
36 | $alert = $invalid;
37 | $error = true;
38 |
39 | // VALID DATA
40 | } else {
41 |
42 | // LOGIN USER
43 | try {
44 |
45 | $kirby->auth()->login($data['email'], $data['password']);
46 |
47 | } catch (Exception $e) {
48 |
49 | if(option('debug')) {
50 |
51 | $alert['error'] = 'Invalid email or password: ' . $e->getMessage();
52 | }
53 | else {
54 |
55 | $alert['error'] = 'Invalid email or password!';
56 | }
57 | }
58 |
59 | // SUCCESSFUL
60 | if (empty($alert) === true) {
61 |
62 | $data = [];
63 | go();
64 | }
65 | }
66 | // INVALID CSRF TOKEN
67 | } else {
68 |
69 | $alert['error'] = 'Invalid CSRF token!';
70 | }
71 | }
72 |
73 | return [
74 | 'error' => $error,
75 | 'alert' => $alert,
76 | 'data' => $data ?? false
77 | ];
78 | };
--------------------------------------------------------------------------------
/site/templates/user.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | = $success ?? '' ?>
6 |
7 |
32 |
33 |
34 | = $page->export()->html() ?> ( JSON | CSV )
35 |
36 |
37 |
50 |
51 |
--------------------------------------------------------------------------------
/site/config/config.php:
--------------------------------------------------------------------------------
1 | true,
12 | 'panel' =>[
13 | 'install' => true
14 | ],
15 | 'user.email.activation' => false,
16 | 'user.email.activation.sender' => '...',
17 | 'user.email.activation.subject' => 'Account Activation Link',
18 | 'routes' => [
19 | [
20 | 'pattern' => 'logout',
21 | 'action' => function() {
22 |
23 | if ($user = kirby()->user()) {
24 | $user->logout();
25 | }
26 |
27 | go('login');
28 |
29 | }
30 | ],
31 | [
32 | 'pattern' => 'user/activate/(:alphanum)',
33 | 'action' => function($token) {
34 |
35 | if (option('user.email.activation', false) === false) {
36 | go();
37 | }
38 |
39 | $kirby = kirby();
40 | $kirby->impersonate('kirby');
41 |
42 | if ($user = $kirby->users()->findBy('emailActivationToken', $token)) {
43 |
44 | if ($user->emailActivationToken()->toString() === Str::toType($token, 'string')) {
45 |
46 | $user->update([
47 | 'emailActivation' => true
48 | ]);
49 |
50 | $kirby->impersonate();
51 | go();
52 | //go('CUSTOM_SUCCESSFUL_ACTIVATION_PAGE');
53 |
54 | }
55 | else {
56 | $kirby->impersonate();
57 | return false;
58 | //go('CUSTOM_ERROR_ACTIVATION_PAGE');
59 | //return page('CUSTOM_ERROR_ACTIVATION_PAGE');
60 | }
61 |
62 | }
63 |
64 | $kirby->impersonate();
65 | }
66 | ]
67 | ],
68 | 'email' => [
69 | 'transport' => [
70 | 'type' => 'smtp',
71 | 'host' => '...',
72 | 'port' => 587,
73 | 'security' => 'tls',
74 | 'auth' => true,
75 | 'username' => '...',
76 | 'password' => '..'
77 | ]
78 | ]
79 | ];
80 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This is a Kirby User Management Add-On!
2 | # (Based on Kirby´s Starterkit)
3 | # ------------
4 |
5 | index.php
6 | favicon.ico
7 | .htaccess
8 | composer.json
9 |
10 | assets
11 |
12 | content/home
13 | content/1_photography
14 | content/2_notes
15 | content/3_about
16 | content/error
17 | content/sandbox
18 |
19 | site/blueprints/site.yml
20 |
21 | site/blueprints/fields
22 | site/blueprints/files
23 | site/blueprints/users/default.yml
24 |
25 | site/blueprints/pages/about.yml
26 | site/blueprints/pages/album.yml
27 | site/blueprints/pages/default.yml
28 | site/blueprints/pages/error.yml
29 | site/blueprints/pages/home.yml
30 | site/blueprints/pages/note.yml
31 | site/blueprints/pages/notes.yml
32 | site/blueprints/pages/photography.yml
33 | site/blueprints/pages/albums.yml
34 |
35 | site/blueprints/sections/albums.yml
36 | site/blueprints/sections/notes.yml
37 |
38 | site/collections
39 |
40 | site/controllers/album.php
41 | site/controllers/note.php
42 | site/controllers/notes.php
43 |
44 | site/models
45 |
46 | site/snippets/footer.php
47 | site/snippets/gallery.php
48 | site/snippets/intro.php
49 | site/snippets/layout.php
50 | site/snippets/layouts.php
51 | site/snippets/note.php
52 | site/snippets/pagination.php
53 | site/snippets/prevnext.php
54 | site/snippets/social.php
55 | site/snippets/image.php
56 | site/snippets/blocks
57 |
58 | site/templates/about.php
59 | site/templates/album.php
60 | site/templates/default.php
61 | site/templates/home.php
62 | site/templates/note.php
63 | site/templates/notes.php
64 | site/templates/photography.php
65 |
66 | # System files
67 | # ------------
68 |
69 | Icon
70 | .DS_Store
71 |
72 | # Temporary files
73 | # ---------------
74 |
75 | /media/*
76 | !/media/index.html
77 |
78 | # Lock files
79 | # ---------------
80 | .lock
81 |
82 | # -------------SECURITY-------------
83 | # NEVER publish these files via Git!
84 | # -------------SECURITY-------------
85 |
86 | # Cache Files
87 | # ---------------
88 |
89 | /site/cache
90 |
91 | # Accounts
92 | # ---------------
93 |
94 | /site/accounts/*
95 | !/site/accounts/index.html
96 |
97 | # Sessions
98 | # ---------------
99 |
100 | /site/sessions/*
101 | !/site/sessions/index.html
102 |
103 | # License
104 | # ---------------
105 | /site/config/.license
--------------------------------------------------------------------------------
/.github/workflows/update-kirby-submodule.yml:
--------------------------------------------------------------------------------
1 | name: Update Kirby Submodule
2 |
3 | on:
4 | schedule:
5 | - cron: '0 6 1 * *' # Monthly on 1st at 06:00 UTC
6 | workflow_dispatch:
7 |
8 | jobs:
9 | update-kirby:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout repository
14 | uses: actions/checkout@v4
15 | with:
16 | submodules: recursive
17 | fetch-depth: 0
18 |
19 | - name: Configure Git (main + submodule)
20 | run: |
21 | git config user.name "github-actions"
22 | git config user.email "github-actions@github.com"
23 | cd kirby
24 | git config user.name "github-actions"
25 | git config user.email "github-actions@github.com"
26 | cd -
27 |
28 | - name: Get previous kirby tag
29 | id: previous
30 | run: |
31 | cd kirby
32 | git fetch --tags
33 | prev_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
34 | echo "prev_tag=$prev_tag" >> $GITHUB_OUTPUT
35 |
36 | - name: Update kirby submodule
37 | run: |
38 | git submodule update --remote --checkout kirby
39 |
40 | - name: Get latest kirby tag after update
41 | id: latest
42 | run: |
43 | cd kirby
44 | git fetch --tags
45 | latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
46 | echo "latest_tag=$latest_tag" >> $GITHUB_OUTPUT
47 |
48 | - name: Skip if no tag or no change
49 | if: steps.latest.outputs.latest_tag == '' || steps.latest.outputs.latest_tag == steps.previous.outputs.prev_tag
50 | run: |
51 | echo "No new tag or tag unchanged — skipping PR creation."
52 | exit 0
53 |
54 | - name: Create Pull Request
55 | uses: peter-evans/create-pull-request@v6
56 | with:
57 | commit-message: "chore: update kirby to ${{ steps.latest.outputs.latest_tag }}"
58 | title: "Update kirby submodule to ${{ steps.latest.outputs.latest_tag }}"
59 | body: |
60 | This PR updates the `kirby` submodule from **${{ steps.previous.outputs.prev_tag }}** to **${{ steps.latest.outputs.latest_tag }}**.
61 |
62 | 🔍 [View changes on GitHub](https://github.com/getkirby/kirby/compare/${{ steps.previous.outputs.prev_tag }}...${{ steps.latest.outputs.latest_tag }})
63 |
64 | branch: "update-kirby-submodule"
65 | delete-branch: true
66 |
--------------------------------------------------------------------------------
/site/snippets/header.php:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 | = $site->title() ?> | = $page->title() ?>
28 |
29 |
36 | = css([
37 | 'assets/css/prism.css',
38 | 'assets/css/lightbox.css',
39 | 'assets/css/index.css',
40 | '@auto'
41 | ]) ?>
42 |
43 |
50 |
51 |
52 |
53 |
54 | = e(option('debug'), " Kirby v" . Kirby::version() . " | PHP " . phpversion())?>
55 |
56 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/site/controllers/register.php:
--------------------------------------------------------------------------------
1 | user()) {
6 | go('/');
7 | }
8 |
9 | $error = null;
10 | $alert = null;
11 |
12 | // TOKEN FOR ACCOUNT ACTIVATION
13 | $token = Str::random(16);
14 |
15 | if($kirby->request()->is('POST') && get('register')) {
16 |
17 | // CHECK HONEYPOT
18 | if(empty(get('username')) === false) {
19 | go('//localhost');
20 | exit;
21 | }
22 |
23 | // VALIDATE CSRF TOKEN
24 | if (csrf(get('csrf')) === true) {
25 |
26 | // GET FORM DATA
27 | $data = [
28 | 'email' => get('email'),
29 | 'password' => get('password')
30 | ];
31 |
32 | $rules = [
33 | 'email' => ['required', 'email'],
34 | 'password' => ['required', 'minLength' => 8]
35 | ];
36 |
37 | $messages = [
38 | 'email' => 'Please enter a valid email adress',
39 | 'password' => 'Please enter a valid password'
40 | ];
41 |
42 | // VALIDATE FORM DATA
43 | if($invalid = invalid($data, $rules, $messages)) {
44 |
45 | $alert = $invalid;
46 | $error = true;
47 |
48 | } else {
49 |
50 | $kirby = kirby();
51 | $kirby->impersonate('kirby');
52 |
53 | try {
54 |
55 | // CREATE USER
56 | $user = $kirby->users()->create([
57 | 'email' => $data['email'],
58 | 'role' => 'user',
59 | 'language' => 'en',
60 | 'password' => $data['password']
61 | ]);
62 |
63 | // CHECK EMAIL ACTIVATION
64 | if (option('user.email.activation', false) === true) {
65 |
66 | $user->update([
67 | 'emailActivation' => false,
68 | 'emailActivationToken' => $token
69 | ]);
70 | }
71 |
72 | } catch(Exception $e) {
73 |
74 | if(option('debug')) {
75 |
76 | $alert['error'] = 'The user could not be created: ' . $e->getMessage();
77 | }
78 | else {
79 |
80 | $alert['error'] = 'The user could not be created!';
81 | }
82 | }
83 |
84 | $kirby->impersonate();
85 |
86 | // SUCCESSFUL
87 | if (empty($alert) === true && $user) {
88 |
89 | // ACTIVATE ACCOUNT BY EMAIL IF ENABLED
90 | if (option('user.email.activation', false) === true) {
91 |
92 | $link = $kirby->site()->url() . "/user/activate/" . $token;
93 |
94 | $email = $kirby->email([
95 | 'to' => $data['email'],
96 | 'from' => option('user.email.activation.sender'),
97 | 'subject' => option('user.email.activation.subject', 'Account Activation Link'),
98 | 'template' => 'account-activation',
99 | 'data' => [
100 | 'link' => $link,
101 | ]
102 | ]);
103 | }
104 |
105 | // LOGIN USER
106 | if($user->login($data['password'])) {
107 | go();
108 | }
109 |
110 | $data = [];
111 | }
112 | }
113 | // INVALID CSRF TOKEN
114 | } else {
115 |
116 | $alert['error'] = 'Invalid CSRF token!';
117 | }
118 | };
119 |
120 | return [
121 | 'error' => $error,
122 | 'alert' => $alert,
123 | 'data' => $data ?? false
124 | ];
125 | };
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Kirby Userkit Add-On (Template)
2 |
3 | * [What do you get?](#what-do-you-get)
4 | * [Why an Add-On?](#why-an-add-on)
5 | * [Installation](#installation)
6 | * [Notes](#notes)
7 | * [Kirby CMS Licence](#kirby-cms-licence)
8 | * [Support](#support)
9 | * [Contribute](#contribute)
10 |
11 |
12 | ## What do you get?
13 | A functional, lean, and unstyled Kirby User Management Add-On (Template) for Kirby CMS.
14 |
15 | **Functionality** | **Comment**
16 | --------------------------- | ---------------------------
17 | Register / Login | Yes
18 | Activation by Email | Yes (Disabled by dafault)
19 | Logout | Virtual
20 | Change Email | Yep
21 | Change Password | Sure
22 | Export Data | CSV & JSON
23 | Dedicated Role | Of course
24 | CSS | Nope
25 | Data Validation | Yes
26 | Success Messages | Partly (Best is to do it manually to adapt to **YOUR** way of working.)
27 | Messages | Mix of hardcoded and page content
28 |
29 | ## Why not use login with Google/Facebook/etc.?
30 | Short answer: **Simplicity and Privacy**. An individual solution like this keeps it simple and create a stronger bond between you and your visitors. No dependency on third parties like Firebase, Okta, OAuth2, etc.
31 |
32 | ## Why an Add-On?
33 | IMHO a Plug-in does not make sense due to interoperability. Also this kind of Add-On adapts way more easy to **YOUR** project and way of working.
34 |
35 | ## Installation:
36 | 1. Download the repository
37 | 2. Unzip the files.
38 | 3. Paste (overwrite) the folder *content* and *site* on top of the root folder of your Kirby installation.
39 | 4. Done!
40 |
41 | ### Configuration
42 | - Set `email` config (see [Kirby email options](https://getkirby.com/docs/reference/system/options/email))
43 | - Set `user.email.activation` config to true (default false).
44 | - Set `user.email.activation.sender` config email sender (mandatory when email activation is enabled).
45 | - Set `user.email.activation.subject` config email subject (mandatory when email activation is enabled).
46 | - Change activation token length in `register.php` controller (default 16).
47 |
48 | ## Notes:
49 | This Add-On is built for Kirby CMS based on **Kirby´s Starterkit Version 4.0.2**.
50 |
51 | In case you are using Kirby´s Plainkit ensure to add the pages/links for the following pages somewhere in your snippets or templates!
52 |
53 | - Register
54 | - Login
55 | - Logout
56 | - User
57 |
58 | > :warning: Last Login have been removed since hooks make life more difficult.
59 |
60 | The user will be logged in even the account is not activated by email yet!
61 | You can check `$kirby->user()->emailActivation()` for disabling certain features, pages etc.
62 |
63 | To change the email template go to `templates\email\account-activation.*.php`.
64 |
65 | In case the user changes the email address the activation status is set to `false`and another email will be sent.
66 |
67 | ### Kirby CMS Licence
68 | **Kirby CMS requires a dedicated licence:**
69 |
70 | *Go to https://getkirby.com/buy*
71 |
72 | ## Disclaimer
73 | The source code is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please create a new issue.
74 |
75 | ## Support
76 |
77 | In case this Add-On saved you some time and energy consider supporting kreativ-anders by donating via [PayPal](https://paypal.me/kreativanders) or becoming a **GitHub Sponsor**.
78 |
79 | ## Contribute
80 |
81 | Feel free to fork the repository and participate.
82 |
--------------------------------------------------------------------------------
/site/controllers/user.php:
--------------------------------------------------------------------------------
1 | user()) {
6 | go('/');
7 | }
8 |
9 | $error = null;
10 | $alert = null;
11 |
12 | // CHECK ACCOUNT ACTIVATION
13 | if(option('user.email.activation', false) === true && $kirby->user()->emailActivation()->toString() === '' || $kirby->user()->emailActivation() != true) {
14 |
15 | $alert['error'] = 'Please check your emails to activate the account.';
16 | }
17 |
18 | // UPDATE USER
19 | if($kirby->request()->is('post') && get('update')) {
20 |
21 | // VALIDATE CSRF TOKEN
22 | if (csrf(get('csrf')) === true) {
23 |
24 | // GET FORM DATA
25 | $data = [
26 | 'email' => get('email'),
27 | 'password' => get('password')
28 | ];
29 |
30 | $rules = [
31 | 'email' => ['email'],
32 | 'password' => ['minLength' => 8]
33 | ];
34 |
35 | $messages = [
36 | 'email' => 'Please enter a valid email adress',
37 | 'password' => 'Please enter an eight character password'
38 | ];
39 |
40 | // VALIDATE FORM DATA
41 | if($invalid = invalid($data, $rules, $messages)) {
42 |
43 | $alert = $invalid;
44 | $error = true;
45 |
46 | // VALID DATA
47 | } else {
48 |
49 | // EMAIL
50 | if (V::email($data['email']) && !get('password')) {
51 |
52 | try {
53 |
54 | $kirby->user()->changeEmail($data['email']);
55 | $success = 'Your email has been changed!';
56 |
57 | // TOKEN FOR ACCOUNT RE-ACTIVATION
58 | $token = Str::random(16);
59 |
60 | $kirby->user()->update([
61 | 'emailActivation' => false,
62 | 'emailActivationToken' => $token
63 | ]);
64 |
65 | // ACTIVATE ACCOUNT BY EMAIL IF ENABLED
66 | if (option('user.email.activation', false) === true) {
67 |
68 | $link = $kirby->site()->url() . "/user/activate/" . $token;
69 |
70 | $email = $kirby->email([
71 | 'to' => $data['email'],
72 | 'from' => option('user.email.activation.sender'),
73 | 'subject' => option('user.email.activation.subject', 'Account Activation Link'),
74 | 'template' => 'account-activation',
75 | 'data' => [
76 | 'link' => $link,
77 | ]
78 | ]);
79 | }
80 |
81 | } catch(Exception $e) {
82 |
83 | if(option('debug')) {
84 |
85 | $alert['error'] = 'The user email could not be changed: ' . $e->getMessage();
86 | }
87 | else {
88 |
89 | $alert['error'] = 'The user email could not be changed!';
90 | }
91 | }
92 | }
93 |
94 | // PASSWORD
95 | if ($data['password']) {
96 |
97 | try {
98 |
99 | $kirby->user()->changePassword($data['password']);
100 | $success = 'Your password has been changed!';
101 |
102 | } catch(Exception $e) {
103 |
104 | if(option('debug')) {
105 |
106 | $alert['error'] = 'The user password could not be changed: ' . $e->getMessage();
107 | }
108 | else {
109 |
110 | $alert['error'] = 'The user password could not be changed!';
111 | }
112 | }
113 | }
114 |
115 | // SUCCESSFUL
116 | if (empty($alert) === true) {
117 |
118 | $error = null;
119 | }
120 | }
121 | // INVALID CSRF TOKEN
122 | } else {
123 |
124 | $alert['error'] = 'Invalid CSRF token!';
125 | }
126 | }
127 |
128 | // DELETE USER
129 | if($kirby->request()->is('post') && get('delete')) {
130 |
131 | try {
132 |
133 | $kirby->user()->delete();
134 | go('/');
135 |
136 | } catch(Exception $e) {
137 |
138 | if(option('debug')) {
139 |
140 | $alert['error'] = 'The user could not be deleted: ' . $e->getMessage();
141 | }
142 | else {
143 |
144 | $alert['error'] = 'The user could not be deleted!';
145 | }
146 | }
147 | }
148 |
149 | return [
150 | 'error' => $error,
151 | 'alert' => $alert,
152 | 'data' => $data ?? false,
153 | 'success' => $success ?? false
154 | ];
155 | };
--------------------------------------------------------------------------------