├── app ├── view │ ├── template │ │ ├── component │ │ │ ├── breadcrumb │ │ │ │ ├── breadcrumb.stache │ │ │ │ └── breadcrumb_item.stache │ │ │ ├── user │ │ │ │ ├── shortcuts_filter_sidebar_section.stache │ │ │ │ ├── dragged_user.ejs │ │ │ │ ├── grid │ │ │ │ │ ├── cell_avatar.stache │ │ │ │ │ ├── grid_filtered_empty.stache │ │ │ │ │ ├── column_header_select.stache │ │ │ │ │ └── grid_item.stache │ │ │ │ ├── primary_sidebar.stache │ │ │ │ ├── disable_mfa_confirm.stache │ │ │ │ ├── delete_confirm.stache │ │ │ │ ├── workspace.stache │ │ │ │ ├── workspace_primary_menu.stache │ │ │ │ ├── groups_filter_sidebar_section.stache │ │ │ │ ├── delete_error_dialog.stache │ │ │ │ ├── information_sidebar_section.stache │ │ │ │ └── user_secondary_sidebar.stache │ │ │ ├── workspace │ │ │ │ ├── secondary_sidebar.stache │ │ │ │ ├── primary_sidebar.stache │ │ │ │ ├── create_button.stache │ │ │ │ ├── import_button.ejs │ │ │ │ ├── import_button.stache │ │ │ │ └── secondary_menu.stache │ │ │ ├── tag │ │ │ │ ├── tree_item.stache │ │ │ │ ├── tag_delete_confirmation_dialog.stache │ │ │ │ ├── tag_filter_sidebar_item.stache │ │ │ │ └── tags_filter_sidebar_section.stache │ │ │ ├── password │ │ │ │ ├── shortcuts_filter_sidebar_section.stache │ │ │ │ ├── grid │ │ │ │ │ ├── cell_username_template.stache │ │ │ │ │ ├── column_header_favorite.stache │ │ │ │ │ ├── grid_owner_empty.stache │ │ │ │ │ ├── grid_favorite_empty.stache │ │ │ │ │ ├── cell_secret_template.stache │ │ │ │ │ ├── column_header_select.stache │ │ │ │ │ ├── grid_group_empty.stache │ │ │ │ │ ├── grid_filtered_empty.stache │ │ │ │ │ ├── grid_shared_empty.stache │ │ │ │ │ ├── grid_welcome.stache │ │ │ │ │ └── cell_uri_template.stache │ │ │ │ ├── primary_sidebar.stache │ │ │ │ ├── workspace.stache │ │ │ │ ├── delete_confirm.stache │ │ │ │ ├── groups_filter_sidebar_section.stache │ │ │ │ ├── folders_filter_sidebar_section.stache │ │ │ │ ├── tag_sidebar_section.stache │ │ │ │ ├── description_sidebar_section.stache │ │ │ │ ├── workspace_primary_menu.stache │ │ │ │ ├── password_secondary_sidebar.stache │ │ │ │ └── information_sidebar_section.stache │ │ │ ├── comment │ │ │ │ ├── delete_confirm.stache │ │ │ │ ├── comments_sidebar_section.stache │ │ │ │ └── comment_item.stache │ │ │ ├── favorite │ │ │ │ └── favorite.stache │ │ │ ├── footer │ │ │ │ └── notification.stache │ │ │ ├── secret │ │ │ │ └── secret_strength.ejs │ │ │ ├── administration │ │ │ │ ├── mfa │ │ │ │ │ ├── primary_menu.stache │ │ │ │ │ └── settings.stache │ │ │ │ ├── email_notification │ │ │ │ │ ├── primary_menu.stache │ │ │ │ │ └── settings.stache │ │ │ │ ├── workspace.stache │ │ │ │ └── users_directory │ │ │ │ │ ├── settings.stache │ │ │ │ │ ├── primary_menu.stache │ │ │ │ │ ├── synchronize_report.stache │ │ │ │ │ └── synchronize_simulation_report.stache │ │ │ ├── group │ │ │ │ ├── delete_confirm.stache │ │ │ │ ├── delete_confirm.ejs │ │ │ │ ├── group_item.stache │ │ │ │ ├── group_members_list_item.stache │ │ │ │ ├── group_secondary_sidebar.stache │ │ │ │ ├── edit.stache │ │ │ │ ├── information_sidebar_section.stache │ │ │ │ └── group_user_list_item.stache │ │ │ ├── settings │ │ │ │ ├── theme.stache │ │ │ │ ├── theme_item.stache │ │ │ │ ├── workspace.stache │ │ │ │ └── workspace_primary_menu.stache │ │ │ ├── session │ │ │ │ └── session_expired.stache │ │ │ ├── mfa │ │ │ │ └── mfa_required.stache │ │ │ ├── group_user │ │ │ │ ├── user_groups_sidebar_section.stache │ │ │ │ ├── user_groups_list_item.stache │ │ │ │ └── group_users_sidebar_section.stache │ │ │ ├── permission │ │ │ │ ├── permissions_sidebar_list_item.stache │ │ │ │ └── permissions_sidebar_section.stache │ │ │ ├── navigation │ │ │ │ └── filter.stache │ │ │ ├── folder │ │ │ │ └── folder_item.stache │ │ │ ├── activity │ │ │ │ ├── resource_activity_sidebar_section.stache │ │ │ │ └── resource_activity_item.stache │ │ │ ├── profile │ │ │ │ ├── header_dropdown.stache │ │ │ │ └── profile.stache │ │ │ ├── gpgkey │ │ │ │ ├── gpgkey_sidebar_section.stache │ │ │ │ └── keys.stache │ │ │ └── dialog │ │ │ │ └── progress.stache │ │ ├── form │ │ │ ├── group │ │ │ │ ├── create.stache │ │ │ │ └── delete_transfer_permissions.stache │ │ │ ├── user │ │ │ │ ├── avatar.stache │ │ │ │ ├── create.stache │ │ │ │ └── delete_transfer_permissions.stache │ │ │ ├── tag │ │ │ │ ├── edit.stache │ │ │ │ └── resource_tag_update.stache │ │ │ ├── resource │ │ │ │ └── edit_description.stache │ │ │ ├── comment │ │ │ │ └── add.stache │ │ │ └── administration │ │ │ │ ├── email_notification │ │ │ │ └── settings.stache │ │ │ │ └── mfa │ │ │ │ └── settings.stache │ │ └── app.stache │ └── component │ │ ├── workspace │ │ ├── secondary_sidebar.js │ │ └── primary_sidebar_section.js │ │ ├── navigation │ │ └── filter.js │ │ ├── favorite │ │ └── favorite.js │ │ ├── group │ │ ├── groups_list.js │ │ └── edit.js │ │ ├── user │ │ └── grid.js │ │ └── permission │ │ └── permissions.js ├── config │ ├── config.json │ └── routes.js ├── error │ ├── error_handler.js │ └── exception.js ├── model │ ├── state │ │ ├── loadingState.js │ │ └── secondary_sidebar_state.js │ ├── map │ │ ├── secret.js │ │ ├── notification.js │ │ ├── image_storage.js │ │ ├── group_user.js │ │ ├── action_log.js │ │ ├── theme.js │ │ ├── permission_type.js │ │ ├── accountSetting.js │ │ ├── group_delete.js │ │ ├── role.js │ │ ├── profile.js │ │ ├── tag.js │ │ ├── comment.js │ │ └── email_notification_settings.js │ ├── action_log_detail │ │ └── action_log_detail.js │ ├── service │ │ ├── users_directory.js │ │ └── plugin │ │ │ ├── auth.js │ │ │ └── group.js │ └── filter.js ├── util │ ├── clipboard.js │ └── lock.js ├── form │ ├── user │ │ └── edit_avatar.js │ ├── group │ │ └── create.js │ ├── resource │ │ └── edit_description.js │ └── comment │ │ └── create.js └── component │ ├── workspace │ ├── primary_sidebar.js │ ├── primary_sidebar_section.js │ ├── secondary_sidebar_section.js │ ├── secondary_sidebar.js │ └── secondary_menu.js │ ├── gpgkey │ ├── keys.js │ └── gpgkey_sidebar_section.js │ ├── administration │ ├── mfa │ │ └── primary_menu.js │ ├── email_notification │ │ └── primary_menu.js │ └── users_directory │ │ └── primary_menu.js │ ├── user │ ├── information_sidebar_section.js │ ├── workspace_groups_filter.js │ ├── groups_filter_sidebar_section.js │ └── primary_sidebar.js │ ├── settings │ └── mfa.js │ ├── group │ ├── information_sidebar_section.js │ └── password_categories_groups_list.js │ ├── dialog │ └── progress.js │ ├── password │ ├── groups_filter_sidebar_section.js │ └── primary_sidebar.js │ ├── profile │ └── profile.js │ ├── session │ └── session_expired.js │ ├── mfa │ └── mfa_required.js │ └── comment │ └── comments_list.js ├── .gitignore ├── favicon.ico ├── pages └── install.js ├── src ├── legacy │ ├── util │ │ ├── plugin.js │ │ └── clipboard.js │ └── config │ │ └── config.js └── components │ └── Common │ └── UserAvatar │ ├── GroupAvatar.js │ └── UserAvatar.js ├── test ├── case │ ├── app │ │ └── model │ │ │ └── map │ │ │ └── safeUrl.stache │ └── all.js ├── test.html └── bootstrap.js ├── .travis.yml ├── .editorconfig ├── passbolt.js ├── stealconfig.js ├── Gruntfile.js └── README.md /app/view/template/component/breadcrumb/breadcrumb.stache: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | ._* 4 | 5 | node_modules 6 | npm-debug.log 7 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/passbolt/passbolt-appjs/HEAD/favicon.ico -------------------------------------------------------------------------------- /pages/install.js: -------------------------------------------------------------------------------- 1 | function reload() { 2 | window.location.reload(); 3 | return false; 4 | } -------------------------------------------------------------------------------- /app/view/template/component/user/shortcuts_filter_sidebar_section.stache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/view/template/component/workspace/secondary_sidebar.stache: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/legacy/util/plugin.js: -------------------------------------------------------------------------------- 1 | import Plugin from "../../../app/util/plugin"; 2 | 3 | export default Plugin; 4 | -------------------------------------------------------------------------------- /src/legacy/config/config.js: -------------------------------------------------------------------------------- 1 | import Config from "passbolt-mad/config/config"; 2 | 3 | export default Config; 4 | -------------------------------------------------------------------------------- /app/view/template/component/workspace/primary_sidebar.stache: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /test/case/app/model/map/safeUrl.stache: -------------------------------------------------------------------------------- 1 | {{uri}} 2 | -------------------------------------------------------------------------------- /app/view/template/component/workspace/create_button.stache: -------------------------------------------------------------------------------- 1 | 2 | create 3 | -------------------------------------------------------------------------------- /app/view/template/component/workspace/import_button.ejs: -------------------------------------------------------------------------------- 1 | 2 | upload -------------------------------------------------------------------------------- /app/view/template/component/tag/tree_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 | {{ mappedItem.label }} 3 |
  • 4 | -------------------------------------------------------------------------------- /app/view/template/component/workspace/import_button.stache: -------------------------------------------------------------------------------- 1 | 2 | upload -------------------------------------------------------------------------------- /app/view/template/component/password/shortcuts_filter_sidebar_section.stache: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/view/template/component/password/grid/cell_username_template.stache: -------------------------------------------------------------------------------- 1 |
    2 | {{../mappedItem[name]}} 3 |
    4 | -------------------------------------------------------------------------------- /app/view/template/component/password/grid/column_header_favorite.stache: -------------------------------------------------------------------------------- 1 | 2 | 3 | fav 4 | -------------------------------------------------------------------------------- /app/view/template/component/user/dragged_user.ejs: -------------------------------------------------------------------------------- 1 |
    2 | Move '<%= name %>' in a group 3 |
    -------------------------------------------------------------------------------- /app/view/template/component/user/grid/cell_avatar.stache: -------------------------------------------------------------------------------- 1 | {{ __('Picture of: %s', ../item.profile.fullName())}} -------------------------------------------------------------------------------- /app/view/template/component/comment/delete_confirm.stache: -------------------------------------------------------------------------------- 1 | {{ __('Please confirm you really want to delete the comment. After clicking ok, the comment will be') }} {{ __('deleted permanently') }} 2 | -------------------------------------------------------------------------------- /app/view/template/component/favorite/favorite.stache: -------------------------------------------------------------------------------- 1 | 2 | 3 | fav 4 | 5 | -------------------------------------------------------------------------------- /app/view/template/component/footer/notification.stache: -------------------------------------------------------------------------------- 1 | 2 | {{ status }} 3 | {{ message }} 4 | 5 | -------------------------------------------------------------------------------- /app/view/template/component/user/primary_sidebar.stache: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/view/template/component/breadcrumb/breadcrumb_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 | {{ mappedItem.label }} 4 |
    5 |
  • 6 | -------------------------------------------------------------------------------- /app/view/template/component/secret/secret_strength.ejs: -------------------------------------------------------------------------------- 1 | 2 | <%= __('complexity') %>: <%= strengthLabel %> -------------------------------------------------------------------------------- /app/view/template/component/password/grid/grid_owner_empty.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('You do not own any passwords yet.')}}

    3 |

    {{ __('It does feel a bit empty here. Create your first password.') }}

    4 |
    -------------------------------------------------------------------------------- /app/view/template/component/administration/mfa/primary_menu.stache: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | 4 | {{__('save settings'}} 5 | 6 |
  • 7 | -------------------------------------------------------------------------------- /app/view/template/component/password/grid/grid_favorite_empty.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{__('None of your passwords are yet marked as favorite.')}}

    3 |

    {{__('Add stars to passwords your want to easily find later.')}}

    4 |
    -------------------------------------------------------------------------------- /app/view/template/component/tag/tag_delete_confirmation_dialog.stache: -------------------------------------------------------------------------------- 1 |

    Are you sure you want to delete the tag {{tag.slug}}?

    2 |

    Warning: Once the tag is deleted, it’ll be removed permanently and will not be recoverable.

    3 | -------------------------------------------------------------------------------- /app/view/template/component/password/grid/cell_secret_template.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 | {{ __('copy password to clipboard') }} 4 | 5 |
    6 | -------------------------------------------------------------------------------- /app/view/template/component/password/grid/column_header_select.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 |
    -------------------------------------------------------------------------------- /app/view/template/component/password/grid/grid_group_empty.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    No passwords are shared with this group yet.

    3 |

    Share a password with this group or wait for a team member to share one with this group.

    4 |
    -------------------------------------------------------------------------------- /app/view/template/component/user/grid/grid_filtered_empty.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{__('None of the users matched this search.')}}

    3 |

    {{__('Try another search or use the left panel to navigate into your organization.')}}

    4 |
    -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: xenial 2 | services: 3 | - xvfb 4 | language: node_js 5 | node_js: 6 | - "6" 7 | script: npm install && npm test 8 | addons: 9 | firefox: "latest-esr" 10 | # Install D-Bus here 11 | apt: 12 | packages: 13 | - "dbus-x11" 14 | -------------------------------------------------------------------------------- /app/view/template/component/password/grid/grid_filtered_empty.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('None of your passwords matched this search.')}}

    3 |

    {{ __('Try another search or use the left panel to navigate into your passwords.')}}

    4 |
    -------------------------------------------------------------------------------- /app/view/template/component/password/grid/grid_shared_empty.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{__('No passwords are shared with you yet.')}}

    3 |

    {{__('It does feel a bit empty here. Wait for a team member to share a password with you.')}}

    4 |
    -------------------------------------------------------------------------------- /app/view/template/component/administration/email_notification/primary_menu.stache: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | 4 | {{__('save settings'}} 5 | 6 |
  • 7 | -------------------------------------------------------------------------------- /app/view/template/component/workspace/secondary_menu.stache: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | 4 | <%= __('view sidebar') %> 5 | 6 |
  • 7 | -------------------------------------------------------------------------------- /app/view/template/component/password/grid/grid_welcome.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Welcome to passbolt!') }}

    3 |

    {{ __('It does feel a bit empty here. Create your first password or') }}
    4 | {{ __('wait for a team member to share one with you.') }}

    5 |
    -------------------------------------------------------------------------------- /app/view/template/component/user/grid/column_header_select.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 |
    5 | -------------------------------------------------------------------------------- /app/view/template/component/password/grid/cell_uri_template.stache: -------------------------------------------------------------------------------- 1 |
    2 | {{#if(../mappedItem.safeUrl)}} 3 | {{ ../mappedItem[name] }} 4 | {{#else}} 5 | {{ ../mappedItem[name] }} 6 | {{/if}} 7 |
    8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.js] 13 | indent_size = 2 14 | -------------------------------------------------------------------------------- /app/view/template/component/user/disable_mfa_confirm.stache: -------------------------------------------------------------------------------- 1 |

    2 | {{ __('You are about to disable second-factor authentication (MFA) for the user') }} {{ user.profile.fullName() }} ({{ user.username }}). 3 |

    4 | 5 |

    {{ __('Warning: Existing settings will be lost. This action cannot be undone.') }}

    6 | -------------------------------------------------------------------------------- /app/view/template/component/group/delete_confirm.stache: -------------------------------------------------------------------------------- 1 | {{#if(resources.length > 0)}} 2 | {{ __('This group is associated with %s passwords. All users in this group will lose access to these passwords.', resources.length) }} 3 | {{#else}} 4 | {{ __('This group is not associated with any password. You are good to go!') }} 5 | {{/if}} 6 | -------------------------------------------------------------------------------- /app/view/template/component/user/delete_confirm.stache: -------------------------------------------------------------------------------- 1 |

    {{ __('Are you sure you want to delete') }} {{ user.profile.first_name }} {{ user.profile.last_name }} ({{ user.username }})?

    2 | 3 |

    {{ __('Warning: This action can’t be undone. All the data associated with this user will be permanently deleted.') }}

    4 | -------------------------------------------------------------------------------- /passbolt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @page passbolt Passbolt 3 | * @tag passbolt 4 | * @parent index 5 | * 6 | * The passbolt page 7 | * 8 | */ 9 | import AppBootstrap from './app/bootstrap'; 10 | import $ from 'jquery'; 11 | 12 | $(document).ready(function () { 13 | // Start the application bootstrap. 14 | new AppBootstrap(); 15 | }); 16 | -------------------------------------------------------------------------------- /src/legacy/util/clipboard.js: -------------------------------------------------------------------------------- 1 | import Plugin from './plugin'; 2 | 3 | class Clipboard { 4 | static copy(value, name) { 5 | name = name || null; 6 | const eventData = { 7 | name: name, 8 | data: value 9 | }; 10 | Plugin.send('passbolt.clipboard', eventData); 11 | } 12 | } 13 | 14 | export default Clipboard; 15 | -------------------------------------------------------------------------------- /app/view/template/component/password/primary_sidebar.stache: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/view/template/component/settings/theme.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    {{ __('Theme') }}

    4 |
    5 |
    6 |
      7 |
    8 |
    9 |
    10 |
    11 |
    12 | -------------------------------------------------------------------------------- /app/view/template/component/session/session_expired.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | {{ __('Your session has expired, you will be automatically redirected to the login page.') }} 4 |

    5 |
    6 | 7 |
    8 | 9 |
    10 | -------------------------------------------------------------------------------- /app/view/template/component/settings/theme_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 | 4 | 5 |
    6 | {{ capitalize(mappedItem.name) }} 7 |
    8 |
    9 |
    10 |
  • 11 | -------------------------------------------------------------------------------- /app/view/template/component/mfa/mfa_required.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | {{ __('Your multi factor authentication (MFA) session has expired, you will be automatically redirected to the MFA page.') }} 4 |

    5 |
    6 | 7 |
    8 | 9 |
    10 | -------------------------------------------------------------------------------- /app/view/template/component/user/workspace.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 | 6 |
    7 | 9 |
    10 |
    11 |
    12 | 13 |
    -------------------------------------------------------------------------------- /app/view/template/component/group_user/user_groups_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Groups') }}

    3 |
    4 | 5 |
    6 | 7 | 8 |
    9 | -------------------------------------------------------------------------------- /app/view/template/component/password/workspace.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 7 |
    8 |
    9 |
    10 |
    11 | -------------------------------------------------------------------------------- /app/view/template/form/group/create.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 | 5 |
    6 |
    7 |
    8 |
    9 | -------------------------------------------------------------------------------- /app/view/template/component/group_user/user_groups_list_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 |
    4 |
    {{ mappedItem.name }}
    5 |
    {{ mappedItem.role }}
    6 |
    7 |
    8 |
    9 | 10 |
    11 |
  • -------------------------------------------------------------------------------- /test/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
    11 |
    12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/view/template/component/settings/workspace.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 8 |
    9 | 10 |
    11 | 13 |
    14 |
    15 |
    16 | 17 |
    -------------------------------------------------------------------------------- /app/view/template/component/password/delete_confirm.stache: -------------------------------------------------------------------------------- 1 | {{#if(multipleDelete)}} 2 | {{ __('Please confirm you really want to delete the passwords. After clicking ok, the passwords will be') }} {{ __('deleted permanently') }}. 3 | {{#else}} 4 |

    {{ __('Are you sure you want to delete the password') }} {{#resources}}{{name}}{{/resources}}?

    5 |

    {{ __('Warning: Once the password is deleted, it’ll be removed permanently and will not be recoverable.') }}

    6 | {{/if}} 7 | -------------------------------------------------------------------------------- /app/view/template/component/permission/permissions_sidebar_list_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 |
    4 |
    {{ mappedItem.acoLabel }} ({{ mappedItem.acoDetails }})
    5 |
    {{ mappedItem.permLabel }}
    6 |
    7 |
    8 |
    9 | 10 |
    11 |
  • 12 | -------------------------------------------------------------------------------- /app/view/template/component/group/delete_confirm.ejs: -------------------------------------------------------------------------------- 1 | <% if(resources && resources.length > 0) { %> 2 | <%= __('This group is associated with %s %s. All users in this group will lose access to %s.', 3 | resources.length, 4 | resources.length > 1 ? __('passwords') : __('password'), 5 | resources.length > 1 ? __('these passwords') : __('this password') 6 | ); %> 7 | <% } else { %> 8 | <%= __('This group is not associated with any password. You are good to go!'); %> 9 | <% } %> 10 | -------------------------------------------------------------------------------- /app/view/template/component/user/grid/grid_item.stache: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{#each(columnModels, columnModel=value num=index)}} 4 | 5 | {{#if(columnModel.template)}} 6 | {{>columnModel.template}} 7 | {{#else}} 8 | {{>../cellTemplate}} 9 | {{/if}} 10 | 11 | {{/each}} 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/view/template/component/navigation/filter.stache: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/view/template/component/administration/workspace.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 8 |
    9 | 10 |
    11 | 13 |
    14 |
    15 |
    16 | 17 |
    -------------------------------------------------------------------------------- /app/view/template/component/group_user/group_users_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Group Members') }}

    3 |
    4 | 5 |
    6 | {{#if(editable)}} 7 | 8 | 9 | {{ __('modify') }} 10 | 11 | {{/if}} 12 | 13 | 14 |
    15 | -------------------------------------------------------------------------------- /app/view/template/form/user/avatar.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 | 6 | 7 |
    8 |
    9 | 10 |
    11 | 12 |
    13 | 14 | {{ __('cancel') }} 15 |
    16 | -------------------------------------------------------------------------------- /app/view/template/component/password/groups_filter_sidebar_section.stache: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /app/view/template/component/password/folders_filter_sidebar_section.stache: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /app/view/template/component/comment/comments_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Comments') }}

    3 |
    4 | 5 |
    6 | 7 | 8 | {{ __('create') }} 9 | 10 |
    11 | Retrieving comments 12 |
    13 | 14 |
    -------------------------------------------------------------------------------- /app/view/template/component/folder/folder_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 |
    4 | 7 |
    8 | {{#if(withMenu)}} 9 | {{#if(mappedItem.canEdit)}} 10 |
    11 | more 12 |
    13 | {{/if}} 14 | {{/if}} 15 |
    16 |
  • -------------------------------------------------------------------------------- /app/view/template/component/group/group_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 |
    4 | 7 |
    8 | {{#if(withMenu)}} 9 | {{#if(mappedItem.canEdit)}} 10 |
    11 | more 12 |
    13 | {{/if}} 14 | {{/if}} 15 |
    16 |
  • -------------------------------------------------------------------------------- /app/view/template/component/group/group_members_list_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 |
    4 |
    {{ mappedItem.userFullName }}
    5 |
    {{#if(mappedItem.isAdmin)}}{{ __('Group manager') }}{{else}}{{ __('Member') }}{{/if}}
    6 |
    7 |
    8 |
    9 | picture of {{ mappedItem.userFullName }} 10 |
    11 |
  • 12 | -------------------------------------------------------------------------------- /app/view/template/component/tag/tag_filter_sidebar_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 |
    4 | 7 |
    8 | {{#if(mappedItem.canEdit)}} 9 |
    10 | more 11 |
    12 | {{/if}} 13 |
    14 |
  • -------------------------------------------------------------------------------- /app/view/template/component/settings/workspace_primary_menu.stache: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | 4 | {{ __('edit') }} 5 | 6 | 7 | 8 | {{ __('Public') }} 9 | 10 | 11 | 12 | {{ __('Private') }} 13 | 14 |
  • 15 | -------------------------------------------------------------------------------- /app/view/template/component/user/workspace_primary_menu.stache: -------------------------------------------------------------------------------- 1 | {{#if(isAdmin)}} 2 |
  • 3 | 4 | 5 | {{ __('edit') }} 6 | 7 |
  • 8 |
  • 9 | 10 | 11 | {{ __('delete') }} 12 | 13 |
  • 14 |
  • 15 | 21 |
  • 22 | {{/if}} 23 | -------------------------------------------------------------------------------- /app/view/template/component/user/groups_filter_sidebar_section.stache: -------------------------------------------------------------------------------- 1 | 12 |
    13 | 14 | 15 |
    16 | -------------------------------------------------------------------------------- /app/view/template/component/activity/resource_activity_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Activity') }}

    3 |
    4 | 5 |
    6 | 7 |
    8 | 9 |
    10 | {{ __('more') }} 11 |
    12 |
    13 |
    -------------------------------------------------------------------------------- /app/view/template/component/permission/permissions_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Shared with') }}

    3 |
    4 | 5 |
    6 | {{#if(canAdmin)}} 7 | 8 | 9 | {{ __('edit') }} 10 | 11 | {{/if}} 12 | 13 |
    14 | Retrieving permissions 15 |
    16 | 17 | 18 |
    19 | -------------------------------------------------------------------------------- /app/view/template/component/user/delete_error_dialog.stache: -------------------------------------------------------------------------------- 1 | {{#if(resources)}} 2 | {{ __('This user is the sole owner of') }} {{ resources.length }} {{#if(resources.length>1)}}{{ __('passwords') }}{{#else}}{{__('password')}}{{/if}}: 3 | {{#resources}}{{#if(scope.index)}}, {{/if}}{{ Resource.name }}{{/each}}. 4 |
    5 | {{/if}} 6 | 7 | {{#if(groups)}} 8 | {{ __('This user is the sole manager of') }} {{ groups.length }} {{#if(groups.length>1)}}{{ __('groups') }}{{#else}}{{__('group')}}{{/if}}: 9 | {{#groups}}{{#if(scope.index)}}, {{/if}}{{ Group.name }}{{/each}}. 10 |
    11 | {{/if}} 12 | 13 |
    14 | 15 | {{ __('You need to transfer the ownership to other users before you can proceed.') }} 16 | -------------------------------------------------------------------------------- /app/view/template/component/password/tag_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Tags') }}

    3 |
    4 | 5 |
    6 | 7 | 8 | {{ __('edit') }} 9 | 10 | 11 |
    12 | Retrieving tags 13 |
    14 | 16 |
    17 | -------------------------------------------------------------------------------- /app/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "controllerElt": "#js_app_controller", 4 | "namespace": "passbolt", 5 | "ControllerClassName": "passbolt.component.App" 6 | }, 7 | "ui": { 8 | "workspace": { 9 | "showSidebar": true 10 | } 11 | }, 12 | "notification": { 13 | "timeout": 6000 14 | }, 15 | "error": { 16 | "ErrorHandlerClassName": "passbolt.error.ErrorHandler" 17 | }, 18 | "event": { 19 | "eventBusControllerElt": "#js_bus_controller" 20 | }, 21 | "secret": { 22 | "generator": { 23 | "masks": ["alpha", "uppercase", "digit", "special"], 24 | "length": 13 25 | } 26 | }, 27 | "net": { 28 | "ResponseHandlerClassName": "passbolt.net.ResponseHandler" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/case/all.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | */ 13 | import "test/case/app/model/map/resource"; 14 | import "test/case/app/model/map/mfa_settings"; -------------------------------------------------------------------------------- /app/view/template/component/administration/users_directory/settings.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |

     

    6 |
    7 | 8 |
    9 |

    {{__('Need help?')}}

    10 |

    {{__('Check out our ldap configuration guide')}}

    11 | 12 | 13 | {{__('Read documentation')}} 14 | 15 |
    16 |
    17 |
    18 | -------------------------------------------------------------------------------- /app/view/template/component/administration/mfa/settings.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |

     

    6 |
    7 | 8 |
    9 |

    {{__('Need help?')}}

    10 |

    {{__('Check out our Multi Factor Authentication configuration guide')}}

    11 | 12 | 13 | {{__('Read documentation')}} 14 | 15 |
    16 |
    17 |
    18 | -------------------------------------------------------------------------------- /app/view/template/form/tag/edit.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 5 | 6 | 7 | 8 |
    9 | 10 |
    11 |
    12 | 13 | {{ __('cancel')}} 14 |
    -------------------------------------------------------------------------------- /app/view/template/form/resource/edit_description.stache: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 |
    5 | 6 |
    7 |
    8 |
    9 | 10 |
    11 | 12 | {{__('cancel')}} 13 |
    14 |
    15 | -------------------------------------------------------------------------------- /app/view/template/component/profile/header_dropdown.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {{ user.profile.fullName() }} 4 | 5 |
    6 |
    7 |
    8 | your picture 9 |
    10 |
    11 | 12 | 13 | more 14 | 15 |
    16 | 18 | -------------------------------------------------------------------------------- /app/view/template/component/user/information_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Information') }}

    3 |
    4 | 5 | 19 | -------------------------------------------------------------------------------- /app/view/template/component/password/description_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Description') }}

    3 |
    4 | 5 |
    6 | {{#if(canEdit)}} 7 | 8 | 9 | <%= __('edit') %> 10 | 11 | {{/if}} 12 | 13 | {{#if(resource.description)}} 14 |

    {{resource.description}}

    15 | {{#else}} 16 | {{#if(canEdit)}} 17 | {{__('There is no description yet, click edit to add one')}} 18 | {{#else}} 19 | {{__('There is no description')}} 20 | {{/if}} 21 | {{/if}} 22 |
    23 | -------------------------------------------------------------------------------- /app/view/template/component/tag/tags_filter_sidebar_section.stache: -------------------------------------------------------------------------------- 1 | 15 |
    16 | 17 | 18 |
    19 | -------------------------------------------------------------------------------- /app/view/template/component/group/group_secondary_sidebar.stache: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /app/error/error_handler.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import MadErrorHandler from "passbolt-mad/error/error_handler"; 15 | 16 | const ErrorHandler = MadErrorHandler.extend('passbolt.error.ErrorHandler', /** @static */ { 17 | 18 | }); 19 | 20 | export default ErrorHandler; 21 | -------------------------------------------------------------------------------- /app/model/state/loadingState.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | */ 13 | import ComponentState from 'passbolt-mad/model/state/componentState'; 14 | 15 | const LoadingState = ComponentState.extend({ 16 | loadingProcesses: { 17 | type: 'integer', 18 | default: 0 19 | } 20 | }); 21 | 22 | export default LoadingState; 23 | -------------------------------------------------------------------------------- /app/view/template/component/administration/users_directory/primary_menu.stache: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | 4 | {{__('save settings')}} 5 | 6 |
  • 7 |
  • 8 | 9 | 10 | {{__('test settings')}} 11 | 12 |
  • 13 |
  • 14 | 15 | 16 | {{__('simulate synchronize')}} 17 | 18 |
  • 19 |
  • 20 | 21 | 22 | {{__('synchronize')}} 23 | 24 |
  • 25 | -------------------------------------------------------------------------------- /app/model/map/secret.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import DefineMap from 'passbolt-mad/model/map/map'; 15 | 16 | const Secret = DefineMap.extend('passbolt.model.Secret', { 17 | id: 'string', 18 | data: 'string' 19 | }); 20 | DefineMap.setReference('Secret', Secret); 21 | 22 | export default Secret; 23 | -------------------------------------------------------------------------------- /app/model/state/secondary_sidebar_state.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | */ 13 | import ComponentState from 'passbolt-mad/model/state/componentState'; 14 | 15 | const SecondarySidebarState = ComponentState.extend({ 16 | opened: { 17 | type: 'boolean', 18 | default: false 19 | } 20 | }); 21 | 22 | export default SecondarySidebarState; 23 | -------------------------------------------------------------------------------- /app/view/template/component/group/edit.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 6 |
    7 |
    8 |
    9 | 12 | 13 |
    14 |
    15 |
    16 |
    17 |
    18 |
    19 | {{ __('save') }} 20 | {{ __('cancel') }} 21 |
    22 | -------------------------------------------------------------------------------- /app/view/component/workspace/secondary_sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import View from 'passbolt-mad/view/view'; 15 | 16 | const SecondarySidebarView = View.extend('passbolt.view.component.SecondarySidebar', /** @static */ { 17 | 18 | }, /** @prototype */ { 19 | 20 | }); 21 | 22 | export default SecondarySidebarView; 23 | -------------------------------------------------------------------------------- /app/model/map/notification.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import DefineMap from 'passbolt-mad/model/map/map'; 15 | 16 | const Notification = DefineMap.extend('passbolt.model.Notification', { 17 | status: 'string', 18 | title: 'string' 19 | }); 20 | DefineMap.setReference('Notification', Notification); 21 | 22 | export default Notification; 23 | -------------------------------------------------------------------------------- /app/view/template/component/password/workspace_primary_menu.stache: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 | 4 | {{ __('copy') }} 5 | 6 |
  • 7 |
  • 8 | 9 | 10 | {{ __('edit') }} 11 | 12 |
  • 13 |
  • 14 | 15 | 16 | {{ __('share') }} 17 | 18 |
  • 19 |
  • 20 | 24 |
  • 25 |
  • 26 | 32 |
  • 33 | -------------------------------------------------------------------------------- /app/util/clipboard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.2.0 13 | */ 14 | import Plugin from './plugin'; 15 | 16 | class Clipboard { 17 | static copy(value, name) { 18 | name = name || null; 19 | const eventData = { 20 | name: name, 21 | data: value 22 | }; 23 | Plugin.send('passbolt.clipboard', eventData); 24 | } 25 | } 26 | 27 | export default Clipboard; 28 | -------------------------------------------------------------------------------- /app/view/template/component/group/information_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Information') }}

    3 |
    4 | 5 | -------------------------------------------------------------------------------- /app/view/template/component/administration/users_directory/synchronize_report.stache: -------------------------------------------------------------------------------- 1 |

    2 | {{#if(usersSynchronized)}}{{ usersSynchronized }} user(s){{#if(groupsSynchronized)}} and{{/if}}{{/if}} 3 | {{#if(groupsSynchronized)}}{{ groupsSynchronized }} group(s){{/if}} 4 | {{#if(!resourcesSynchronized)}}No resources{{/if}} 5 | were synchronized 6 |

    7 | {{#if(groupsError || usersError)}} 8 |

    Some resources were not synchronized and require your attention, see the full report.

    9 | {{/if}} 10 | 11 |
    12 |
    13 | {{__('Full report')}} 14 |
    15 | 21 |
    22 | -------------------------------------------------------------------------------- /app/view/template/component/administration/users_directory/synchronize_simulation_report.stache: -------------------------------------------------------------------------------- 1 | 2 |

    3 | {{#if(usersSynchronized)}}{{ usersSynchronized }} user(s){{#if(groupsSynchronized)}} and{{/if}}{{/if}} 4 | {{#if(groupsSynchronized)}}{{ groupsSynchronized }} group(s){{/if}} 5 | {{#if(!resourcesSynchronized)}}No resources{{/if}} 6 | will be synchronized 7 |

    8 | {{#if(groupsError || usersError)}} 9 |

    Some resources won't be synchronized and will require your attention, see the full report.

    10 | {{/if}} 11 | 12 |
    13 |
    14 | {{__('Full report')}} 15 |
    16 | 22 |
    23 | -------------------------------------------------------------------------------- /app/model/action_log_detail/action_log_detail.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SA (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | */ 13 | 14 | import Resource from "../map/resource"; 15 | 16 | class ActionLogDetail { 17 | /** 18 | * Constructor 19 | * @param options 20 | */ 21 | constructor(user, resource) { 22 | this.user = user; 23 | this.resource = resource; 24 | 25 | this.resource.permalink = Resource.getPermalink(resource); 26 | } 27 | } 28 | 29 | export default ActionLogDetail; 30 | -------------------------------------------------------------------------------- /test/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | */ 13 | import $ from 'jquery'; 14 | import "steal-mocha"; 15 | import chai from "chai"; 16 | 17 | // Define the global context. 18 | const glbl = typeof window !== "undefined" ? window : global; 19 | 20 | // Extract the expect & assert functions from chai and make them global 21 | glbl.expect = chai.expect; 22 | glbl.assert = chai.assert; 23 | 24 | // Make a global reference to the root reference element. 25 | glbl.$rootElement = $('#test-html'); 26 | -------------------------------------------------------------------------------- /app/view/template/component/user/user_secondary_sidebar.stache: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /app/view/template/component/comment/comment_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 |
    4 |
    5 |
    6 |

    {{ mappedItem.content }}

    7 | 11 | {{#if(mappedItem.isOwner)}} 12 |
    13 | 21 |
    22 | {{/if}} 23 |
    24 |
    25 |
    26 |
    27 | 30 |
    31 |
    32 |
  • -------------------------------------------------------------------------------- /app/view/component/navigation/filter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import View from 'passbolt-mad/view/view'; 16 | 17 | const FilterView = View.extend('passbolt.view.component.navigation.Filter', /** @static */ { 18 | 19 | }, /** @prototype */ { 20 | 21 | /** 22 | * Observe when the user update the filter 23 | */ 24 | 'form submit': function() { 25 | $(this.element).trigger('update'); 26 | } 27 | 28 | }); 29 | export default FilterView; 30 | -------------------------------------------------------------------------------- /app/view/template/form/tag/resource_tag_update.stache: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /app/form/user/edit_avatar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Form from 'passbolt-mad/form/form'; 15 | 16 | import template from '../../view/template/form/user/avatar.stache'; 17 | 18 | const EditAvatarForm = Form.extend('passbolt.form.user.Avatar', /** @static */ { 19 | 20 | defaults: { 21 | template: template 22 | } 23 | 24 | }, /** @prototype */ { 25 | 26 | /** 27 | * @inheritdoc 28 | */ 29 | afterStart: function() { 30 | // Rebind controller events 31 | this.on(); 32 | } 33 | 34 | }); 35 | export default EditAvatarForm; 36 | -------------------------------------------------------------------------------- /stealconfig.js: -------------------------------------------------------------------------------- 1 | steal.config({ 2 | main: 'passbolt', 3 | map: { 4 | "jquery/jquery": "jquery", 5 | "urijs": "node_modules/urijs/src" 6 | }, 7 | paths: { 8 | "can": "node_modules/can/can.js", 9 | "can/*": "node_modules/can/*.js", 10 | "jquery": "node_modules/jquery/dist/jquery.js", 11 | "moment": "node_modules/moment/moment.js", 12 | "moment-timezone-with-data": "node_modules/moment-timezone/builds/moment-timezone-with-data.js", 13 | "sha1": "node_modules/jssha/src/sha.js", 14 | "underscore": "node_modules/underscore/underscore.js", 15 | "xregexp": "node_modules/xregexp/xregexp-all.js", 16 | "passbolt-mad": "node_modules/passbolt-mad/passbolt-mad.js", 17 | "passbolt-mad/*": "node_modules/passbolt-mad/*.js" 18 | }, 19 | "meta": { 20 | "mocha": { 21 | "format": "global", 22 | "exports": "mocha", 23 | "deps": [ 24 | "steal-mocha/add-dom" 25 | ] 26 | } 27 | }, 28 | ext: { 29 | "ejs": "passbolt-mad/lib/can/viewEjsSystem" 30 | } 31 | }); 32 | System.config({ 33 | buildConfig: { 34 | map: { 35 | "can/util/util": "can/util/domless/domless" 36 | } 37 | } 38 | }); 39 | -------------------------------------------------------------------------------- /app/view/component/favorite/favorite.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import View from 'passbolt-mad/view/view'; 16 | 17 | const FavoriteView = View.extend('passbolt.view.component.favorite.Favorite', /** @static */ { 18 | 19 | }, /** @prototype */ { 20 | 21 | /** 22 | * Mark as a favorite. 23 | */ 24 | favorite: function() { 25 | $('i', this.element).removeClass('fav').addClass('unfav'); 26 | }, 27 | 28 | /** 29 | * Unmark as a favorite. 30 | */ 31 | unfavorite: function() { 32 | $('i', this.element).removeClass('unfav').addClass('fav'); 33 | } 34 | 35 | }); 36 | 37 | export default FavoriteView; 38 | -------------------------------------------------------------------------------- /app/view/template/component/gpgkey/gpgkey_sidebar_section.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    {{ __('Public Key') }}

    3 |
    4 | 5 | 34 | -------------------------------------------------------------------------------- /app/component/workspace/primary_sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | //import PrimarySidebarView from 'app/view/component/workspace/primary_sidebar'; 16 | 17 | import template from '../../view/template/component/workspace/primary_sidebar.stache'; 18 | 19 | const PrimarySidebarComponent = Component.extend('passbolt.component.workspace.PrimarySidebar', /** @static */ { 20 | 21 | defaults: { 22 | label: 'Sidebar Component', 23 | //viewClass: PrimarySidebarView, 24 | template: template 25 | } 26 | 27 | }, /** @prototype */ { 28 | 29 | }); 30 | 31 | export default PrimarySidebarComponent; 32 | -------------------------------------------------------------------------------- /app/util/lock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Based on https://thecodebarbarian.com/mutual-exclusion-patterns-with-node-promises 3 | * @copyright Valeri Karpov 4 | */ 5 | import Events from 'events'; 6 | 7 | export default class Lock { 8 | constructor() { 9 | this._locked = false; 10 | this._ee = new Events.EventEmitter(); 11 | } 12 | 13 | acquire() { 14 | return new Promise(resolve => { 15 | // If nobody has the lock, take it and resolve immediately 16 | if (!this._locked) { 17 | /* 18 | * Safe because JS doesn't interrupt you on synchronous operations, 19 | * so no need for compare-and-swap or anything like that. 20 | */ 21 | this._locked = true; 22 | return resolve(); 23 | } 24 | 25 | // Otherwise, wait until somebody releases the lock and try again 26 | const tryAcquire = () => { 27 | if (!this._locked) { 28 | this._locked = true; 29 | this._ee.removeListener('release', tryAcquire); 30 | return resolve(); 31 | } 32 | }; 33 | this._ee.on('release', tryAcquire); 34 | }); 35 | } 36 | 37 | release() { 38 | // Release the lock immediately 39 | this._locked = false; 40 | this._ee.emit('release'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | */ 13 | 14 | module.exports = function(grunt) { 15 | 16 | grunt.registerTask("test", ["testee:tests"]); 17 | 18 | grunt.initConfig({ 19 | testee: { 20 | tests: { 21 | options: { 22 | browsers: [{ 23 | "browser": "chrome", 24 | "args": [ 25 | "--headless", 26 | "--disable-gpu", 27 | "--remote-debugging-port=9222" 28 | ] 29 | }] 30 | }, 31 | src: ['test/test.html'] 32 | } 33 | } 34 | }); 35 | 36 | grunt.loadNpmTasks('grunt-testee'); 37 | }; -------------------------------------------------------------------------------- /app/component/gpgkey/keys.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | import User from '../../model/map/user'; 16 | 17 | import template from '../../view/template/component/gpgkey/keys.stache'; 18 | 19 | const Keys = Component.extend('passbolt.component.gpgkey.Keys', /** @static */ { 20 | 21 | defaults: { 22 | template: template 23 | } 24 | 25 | }, /** @prototype */ { 26 | 27 | /** 28 | * @inheritdoc 29 | */ 30 | beforeRender: function() { 31 | this._super(); 32 | const gpgKey = User.getCurrent().gpgkey; 33 | this.setViewData('gpgkey', gpgKey); 34 | } 35 | }); 36 | 37 | export default Keys; 38 | -------------------------------------------------------------------------------- /app/error/exception.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | 15 | // Initialize the error namespaces. 16 | passbolt.error = passbolt.error || {}; 17 | passbolt.error.WRONG_PARAMETER = "Wrong parameter [%0]"; 18 | passbolt.error.MISSING_OPTION = "The option [%0] should be defined"; 19 | passbolt.error.ELEMENT_NOT_FOUND = "The element [%0] could not be found"; 20 | 21 | const PassboltException = passbolt.Exception = function() { 22 | }; 23 | 24 | PassboltException.get = function(exception_message) { 25 | const reps = Array.prototype.slice.call(arguments, 1); 26 | const message = exception_message.replace(/%(\d+)/g, (s, key) => reps[key] || s); 27 | return new Error(message); 28 | }; 29 | -------------------------------------------------------------------------------- /app/component/workspace/primary_sidebar_section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | import PrimarySidebarSectionView from '../../view/component/workspace/primary_sidebar_section'; 16 | 17 | //import template from 'app/view/template/component/workspace/sidebar_section.ejs!'; 18 | 19 | const PrimarySidebarSectionComponent = Component.extend('passbolt.component.workspace.SecondarySidebarSection', /** @static */ { 20 | 21 | defaults: { 22 | label: 'Primary Sidebar Section Component', 23 | viewClass: PrimarySidebarSectionView 24 | } 25 | 26 | }, /** @prototype */ { 27 | 28 | }); 29 | 30 | export default PrimarySidebarSectionComponent; 31 | -------------------------------------------------------------------------------- /app/component/administration/mfa/primary_menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.6.0 13 | */ 14 | import Button from 'passbolt-mad/component/button'; 15 | import Component from 'passbolt-mad/component/component'; 16 | import template from '../../../view/template/component/administration/mfa/primary_menu.stache'; 17 | 18 | const PrimaryMenu = Component.extend('passbolt.component.administration.mfa.PrimaryMenu', /** @static */ { 19 | defaults: { 20 | template: template 21 | } 22 | 23 | }, /** @prototype */ { 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | afterStart: function() { 29 | this.saveButton = new Button('#js-mfa-settings-save-button', {state: {disabled: true}}); 30 | this.saveButton.start(); 31 | } 32 | 33 | }); 34 | 35 | export default PrimaryMenu; 36 | -------------------------------------------------------------------------------- /app/model/map/image_storage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import DefineMap from 'passbolt-mad/model/map/map'; 15 | 16 | const ImageStorage = DefineMap.extend('passbolt.model.ImageStorage', { 17 | /** 18 | * Get the image path 19 | * @param {passbolt.model.ImageStorage} img The target image 20 | * @param {string} version (optional) The version to get 21 | * @return {string} The image path 22 | */ 23 | imagePath: function(version) { 24 | if (typeof this.url == 'undefined') { 25 | return ''; 26 | } 27 | if (typeof this.url[version] == 'undefined') { 28 | return ''; 29 | } else { 30 | return this.url[version]; 31 | } 32 | } 33 | }); 34 | DefineMap.setReference('ImageStorage', ImageStorage); 35 | 36 | export default ImageStorage; 37 | -------------------------------------------------------------------------------- /app/component/administration/email_notification/primary_menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SA (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.10.0 13 | */ 14 | import Button from 'passbolt-mad/component/button'; 15 | import Component from 'passbolt-mad/component/component'; 16 | import template from '../../../view/template/component/administration/email_notification/primary_menu.stache'; 17 | 18 | const PrimaryMenu = Component.extend('passbolt.component.administration.email_notification.PrimaryMenu', /** @static */ { 19 | defaults: { 20 | template: template 21 | } 22 | 23 | }, /** @prototype */ { 24 | 25 | /** 26 | * @inheritdoc 27 | */ 28 | afterStart: function() { 29 | this.saveButton = new Button('#js-email-notification-settings-save-button', {state: {disabled: true}}); 30 | this.saveButton.start(); 31 | } 32 | 33 | }); 34 | 35 | export default PrimaryMenu; 36 | -------------------------------------------------------------------------------- /app/component/user/information_sidebar_section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import SecondarySidebarSectionComponent from '../workspace/secondary_sidebar_section'; 15 | 16 | import template from '../../view/template/component/user/information_sidebar_section.stache'; 17 | 18 | const InformationSidebarSectionComponent = SecondarySidebarSectionComponent.extend('passbolt.component.user.InformationSidebarSection', /** @static */ { 19 | 20 | defaults: { 21 | label: 'Sidebar Section Information Controller', 22 | template: template, 23 | user: null 24 | } 25 | 26 | }, /** @prototype */ { 27 | 28 | /** 29 | * @inheritdoc 30 | */ 31 | beforeRender: function() { 32 | this._super(); 33 | this.setViewData('user', this.options.user); 34 | } 35 | 36 | }); 37 | 38 | export default InformationSidebarSectionComponent; 39 | -------------------------------------------------------------------------------- /app/component/settings/mfa.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import AuthService from '../../model/service/plugin/auth'; 16 | import Component from 'passbolt-mad/component/component'; 17 | import HtmlHelper from 'passbolt-mad/helper/html'; 18 | 19 | const MfaComponent = Component.extend('passbolt.component.settings.mfa', /** @static */ { 20 | 21 | defaults: {} 22 | 23 | }, /** @prototype */ { 24 | /** 25 | * @inheritdoc 26 | */ 27 | afterStart: async function() { 28 | const isAuthenticated = await AuthService.isAuthenticated(); 29 | if (isAuthenticated) { 30 | const iframeContent = ``; 31 | HtmlHelper.create($(this.element), 'inside_replace', iframeContent); 32 | } 33 | } 34 | }); 35 | 36 | export default MfaComponent; 37 | -------------------------------------------------------------------------------- /app/component/gpgkey/gpgkey_sidebar_section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import SecondarySidebarSectionComponent from '../workspace/secondary_sidebar_section'; 15 | 16 | import template from '../../view/template/component/gpgkey/gpgkey_sidebar_section.stache'; 17 | 18 | const GpgKeySidebarSectionComponent = SecondarySidebarSectionComponent.extend('passbolt.component.gpgkey.GpgKeySidebarSection', /** @static */ { 19 | 20 | defaults: { 21 | label: 'Sidebar Section Gpgkey Controller', 22 | template: template, 23 | gpgkey: null 24 | } 25 | 26 | }, /** @prototype */ { 27 | 28 | /** 29 | * @inheritdoc 30 | */ 31 | beforeRender: function() { 32 | this._super(); 33 | // pass the new resource to the view 34 | const gpgkey = this.options.gpgkey; 35 | this.setViewData('gpgkey', gpgkey); 36 | } 37 | 38 | }); 39 | 40 | export default GpgKeySidebarSectionComponent; 41 | -------------------------------------------------------------------------------- /src/components/Common/UserAvatar/GroupAvatar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) 2020 Passbolt SA (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) 2020 Passbolt SA (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.13.0 13 | */ 14 | import React, {Component} from "react"; 15 | import PropTypes from "prop-types"; 16 | 17 | class GroupAvatar extends Component { 18 | /** 19 | * Constructor 20 | * @param {Object} props 21 | */ 22 | constructor(props) { 23 | super(props); 24 | } 25 | 26 | getAvatarSrc() { 27 | const trustedDomain = APP_URL; 28 | return `${trustedDomain}/img/avatar/group_default.png`; 29 | } 30 | 31 | getAltText() { 32 | return `Avatar of the ${this.props.group.name} group.`; 33 | } 34 | 35 | render() { 36 | return( 37 |
    38 | {this.getAltText()}/ 39 |
    40 | ) 41 | } 42 | } 43 | 44 | GroupAvatar.propTypes = { 45 | group: PropTypes.object 46 | }; 47 | 48 | export default GroupAvatar; 49 | -------------------------------------------------------------------------------- /app/component/user/workspace_groups_filter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | import Group from '../../model/map/group'; 16 | import PeopleGroupsListComponent from '../group/people_groups_list'; 17 | 18 | import template from '../../view/template/component/user/workspace_groups_filter.ejs!'; 19 | 20 | const WorkspaceGroupsFilterComponent = Component.extend('passbolt.component.user.workspace_groups_filter', /** @static */ { 21 | 22 | defaults: { 23 | template: template, 24 | selectedGroups: new Group.List() 25 | } 26 | 27 | }, /** @prototype */ { 28 | 29 | /** 30 | * @inheritdoc 31 | */ 32 | afterStart: function() { 33 | const peopleGroupsList = new PeopleGroupsListComponent('#js_wsp_users_groups_list', { 34 | selectedGroups: this.options.selectedGroups 35 | }); 36 | peopleGroupsList.start(); 37 | } 38 | 39 | }); 40 | 41 | export default WorkspaceGroupsFilterComponent; 42 | -------------------------------------------------------------------------------- /app/view/template/component/group/group_user_list_item.stache: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 |
    4 | 5 |
    6 | 7 |
    8 |
    9 | {{ mappedItem.userLabel }} 10 |
    11 | 12 |
    13 | 14 |
    {{ mappedItem.userFingerprint }}
    15 |
    16 |
    17 |
    18 |
    19 | {{#if(mappedItem.isNew){{ __('Will be added') }}{{#else}}{{ __('Unchanged') }}{{/if}} 20 |
    21 |
    22 | 23 |
    24 |
    25 | 27 |
    28 |
    29 | 30 |
    31 | 32 | 33 | {{ __('remove') }} 34 | 35 |
    36 | 37 |
  • 38 | -------------------------------------------------------------------------------- /app/component/group/information_sidebar_section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import SecondarySidebarSectionComponent from '../workspace/secondary_sidebar_section'; 15 | 16 | import template from '../../view/template/component/group/information_sidebar_section.stache'; 17 | 18 | const InformationSidebarSectionComponent = SecondarySidebarSectionComponent.extend('passbolt.component.group.InformationSidebarSection', /** @static */ { 19 | 20 | defaults: { 21 | label: 'Sidebar Section Information Controller', 22 | template: template, 23 | group: null 24 | } 25 | 26 | }, /** @prototype */ { 27 | 28 | /** 29 | * @inheritdoc 30 | */ 31 | beforeRender: function() { 32 | this._super(); 33 | this.setViewData('group', this.options.group); 34 | }, 35 | 36 | /** 37 | * Observe when the item is updated 38 | */ 39 | '{group} updated': function() { 40 | this.refresh(); 41 | } 42 | 43 | }); 44 | 45 | export default InformationSidebarSectionComponent; 46 | -------------------------------------------------------------------------------- /app/view/component/workspace/primary_sidebar_section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import View from 'passbolt-mad/view/view'; 16 | 17 | const PrimarySidebarSectionView = View.extend('passbolt.view.component.PrimarySidebarSection', /** @static */ { 18 | 19 | }, /** @prototype */ { 20 | 21 | /** 22 | * Open the section. 23 | */ 24 | open: function() { 25 | $('.accordion-content', this.element).slideDown(50); 26 | $(this.element).removeClass('closed'); 27 | }, 28 | 29 | /** 30 | * Close the section 31 | */ 32 | close: function() { 33 | $('.accordion-content', this.element).slideUp(50); 34 | $(this.element).addClass('closed'); 35 | }, 36 | 37 | /** 38 | * Observe when accordion-header is clicked. 39 | */ 40 | '{element} a.accordion-trigger click': function() { 41 | if ($(this.element).hasClass('closed')) { 42 | this.open(); 43 | } else { 44 | this.close(); 45 | } 46 | } 47 | 48 | }); 49 | 50 | export default PrimarySidebarSectionView; 51 | -------------------------------------------------------------------------------- /app/model/map/group_user.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import DefineList from 'passbolt-mad/model/list/list'; 15 | import DefineMap from 'passbolt-mad/model/map/map'; 16 | import Group from './group'; 17 | import User from './user'; 18 | 19 | const GroupUser = DefineMap.extend('passbolt.model.GroupUser', { 20 | id: 'string', 21 | group_id: 'string', 22 | user_id: 'string', 23 | is_admin: 'boolean', 24 | user: User, 25 | group: Group 26 | }); 27 | DefineMap.setReference('GroupUser', GroupUser); 28 | GroupUser.List = DefineList.extend({'#': {Type: GroupUser}}); 29 | 30 | /** 31 | * Sort the groups users alphabetically. 32 | */ 33 | GroupUser.List.prototype.sortAlphabetically = function() { 34 | this.sort((a, b) => { 35 | const aValue = a.user ? a.user.profile.first_name : a.group.name; 36 | const bValue = b.user ? b.user.profile.first_name : b.group.name; 37 | if (aValue < bValue) { 38 | return -1; 39 | } else if (aValue > bValue) { 40 | return 1; 41 | } 42 | return 0; 43 | }); 44 | }; 45 | 46 | export default GroupUser; 47 | -------------------------------------------------------------------------------- /app/view/template/component/gpgkey/keys.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |

    Information for public and secret key

    5 | 6 | 7 | 8 | 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 |
    Key Id 9 |
    11 | 14 |
    15 |
    Uid{{ gpgkey.uid }}
    Fingerprint{{ gpgkey.fingerprint }}
    Created{{ gpgkey.key_created }}
    Expires{{ gpgkey.expires }}
    Key Length{{ gpgkey.bits }}
    Algorithm{{ gpgkey.type }}
    42 |
    43 |
    44 |

    Public key block

    45 |
    46 | 47 |
    48 |
    49 |
    50 |
    51 | -------------------------------------------------------------------------------- /app/view/template/form/group/delete_transfer_permissions.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | You are about to delete {{group.name}}. 4 |

    5 |

    6 | This group is the owner of passwords. 7 | You need to transfer the ownership to other users or groups to continue. 8 |

    9 |
    10 |
    11 | {{#if(folders.length)}} 12 |

    Folders

    13 | 23 | {{/if}} 24 | {{#if(resources.length)}} 25 |

    Passwords

    26 | 36 | {{/if}} 37 |
    38 | 39 |
    40 | 41 | {{ __('cancel')}} 42 |
    43 | -------------------------------------------------------------------------------- /app/model/service/users_directory.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.6.0 13 | */ 14 | import AppAjax from '../../net/ajax'; 15 | import UsersDirectoryReport from '../../model/map/users_directory_report'; 16 | 17 | class UsersDirectoryService {} 18 | 19 | /** 20 | * Simulate a synchronization 21 | * @return {Promise} 22 | * @static 23 | */ 24 | UsersDirectoryService.dryRunSynchronize = function(params) { 25 | params = params || {}; 26 | params['api-version'] = 'v2'; 27 | return AppAjax.request({ 28 | url: 'directorysync/synchronize/dry-run.json', 29 | type: 'GET', 30 | params: params 31 | }).then(data => new UsersDirectoryReport(data)); 32 | }; 33 | 34 | /** 35 | * Synchronize 36 | * @return {Promise} 37 | * @static 38 | */ 39 | UsersDirectoryService.synchronize = function(params) { 40 | params = params || {}; 41 | params['api-version'] = 'v2'; 42 | return AppAjax.request({ 43 | url: 'directorysync/synchronize.json', 44 | type: 'GET', 45 | params: params 46 | }).then(data => new UsersDirectoryReport(data)); 47 | }; 48 | 49 | export default UsersDirectoryService; 50 | -------------------------------------------------------------------------------- /app/form/group/create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import FeedbackComponent from 'passbolt-mad/form/feedback'; 15 | import Form from 'passbolt-mad/form/form'; 16 | import TextboxComponent from 'passbolt-mad/form/element/textbox'; 17 | 18 | import template from '../../view/template/form/group/create.stache'; 19 | 20 | const CreateForm = Form.extend('passbolt.form.group.Create', /** @static */ { 21 | 22 | defaults: { 23 | action: 'create', 24 | template: template, 25 | cssClasses: ['group_edit_form'], 26 | canUpdateName: true 27 | } 28 | 29 | }, /** @prototype */ { 30 | 31 | /** 32 | * @inheritdoc 33 | */ 34 | afterStart: function() { 35 | // Add user first name field. 36 | this.addElement( 37 | new TextboxComponent('#js_field_name', { 38 | modelReference: 'Group.name', 39 | state: { 40 | disabled: !this.options.canUpdateName 41 | } 42 | }).start(), 43 | new FeedbackComponent('#js_field_name_feedback', {}).start() 44 | ); 45 | 46 | this.on(); 47 | } 48 | 49 | }); 50 | 51 | export default CreateForm; 52 | -------------------------------------------------------------------------------- /app/view/template/app.stache: -------------------------------------------------------------------------------- 1 | 2 |
    3 |
    4 | 5 |
    6 |
    7 | 8 |
    9 |
    10 |
    11 |
    12 | 13 |
    14 | 15 | 26 | 27 |
    28 | 29 |
    30 | 31 |
    32 | 35 |
    36 | 37 |
    38 |
    39 |
    40 |
    41 | 42 |
    43 | 45 |
    46 |
    47 | 48 |
    49 | 50 |
    51 |
    52 | 53 |
    54 |
    55 |
    56 |
    57 |
    58 |
    59 | 60 |
    61 | 62 |
    63 |
    64 | -------------------------------------------------------------------------------- /app/view/template/component/dialog/progress.stache: -------------------------------------------------------------------------------- 1 | 2 |
    3 |
    4 |

    {{label}}{{#if(subtitle)}}{{subtitle}}{{/if}}{{#if(titleInfo)}}
    5 | 6 |
    7 | {{#if(titleInfo.name)}} 8 | {{>titleInfo}} 9 | {{#else}} 10 | {{titleInfo}} 11 | {{/if}} 12 |
    13 |
    {{/if}} 14 |

    15 | 16 | 17 | close 18 | 19 |
    20 |
    21 | 22 |
    23 | 24 |
    25 | 26 | 27 | 28 |
    29 |
    30 |   31 | 32 |
    33 |
    34 |
    35 |
    36 | -------------------------------------------------------------------------------- /app/view/component/group/groups_list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import DomData from 'can-dom-data'; 16 | import domEvents from 'can-dom-events'; 17 | import TreeView from 'passbolt-mad/view/component/tree'; 18 | 19 | const GroupsListView = TreeView.extend('passbolt.view.component.GroupsList', /** @static */ { 20 | 21 | }, /** @prototype */ { 22 | 23 | /** 24 | * Mousedown event. 25 | * 26 | * We use this event to display the contextual menu 27 | * @param {HTMLElement} el The element the event occurred on 28 | * @param {HTMLEvent} ev The event which occurred 29 | * @returns {boolean} 30 | */ 31 | '{element} .more-ctrl a mousedown': function(el, ev) { 32 | ev.stopPropagation(); 33 | ev.preventDefault(); 34 | const $li = $(el).closest('li'); 35 | const itemClass = this.getController().getItemClass(); 36 | const group = DomData.get($li[0], itemClass.shortName); 37 | domEvents.dispatch(this.element, {type: 'item_menu_clicked', data: {group: group, srcEv: ev}}); 38 | 39 | return false; 40 | } 41 | 42 | }); 43 | 44 | export default GroupsListView; 45 | -------------------------------------------------------------------------------- /app/view/template/component/administration/email_notification/settings.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 22 |
    23 |

    {{__('Need some help?')}}

    24 |
    25 |

    {{__('For more information about email notification, checkout the dedicated page on the help website.')}}

    26 | 27 | 28 | {{__('Read documentation')}} 29 | 30 |
    31 |
    32 |
    33 |
    34 | -------------------------------------------------------------------------------- /app/component/workspace/secondary_sidebar_section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import Component from 'passbolt-mad/component/component'; 16 | import SecondarySidebarState from '../../model/state/secondary_sidebar_state'; 17 | 18 | const SecondarySidebarSection = Component.extend('passbolt.component.workspace.SecondarySidebarSection', /** @static */ { 19 | 20 | defaults: { 21 | label: 'SecondarySidebar Component', 22 | stateClass: SecondarySidebarState 23 | } 24 | 25 | }, /** @prototype */ { 26 | 27 | /** 28 | * Open the section. 29 | */ 30 | open: function() { 31 | $('.accordion-content', this.element).slideDown(50); 32 | $(this.element).removeClass('closed'); 33 | this.state.opened = true; 34 | }, 35 | 36 | /** 37 | * Close the section 38 | */ 39 | close: function() { 40 | $('.accordion-content', this.element).slideUp(50); 41 | $(this.element).addClass('closed'); 42 | this.state.opened = false; 43 | }, 44 | 45 | /** 46 | * Observe when accordion-header is clicked. 47 | */ 48 | '{element} a.accordion-trigger click': function() { 49 | if (!this.state.opened) { 50 | this.open(); 51 | } else { 52 | this.close(); 53 | } 54 | } 55 | 56 | }); 57 | 58 | export default SecondarySidebarSection; 59 | -------------------------------------------------------------------------------- /app/model/map/action_log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SA (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Ajax from '../../net/ajax'; 15 | import connect from 'can-connect'; 16 | import connectDataUrl from 'can-connect/data/url/url'; 17 | import connectParse from 'can-connect/data/parse/parse'; 18 | import connectConstructor from 'can-connect/constructor/constructor'; 19 | import connectMap from 'can-connect/can/map/map'; 20 | import DefineList from 'passbolt-mad/model/list/list'; 21 | import DefineMap from 'passbolt-mad/model/map/map'; 22 | import User from './user'; 23 | 24 | const ActionLog = DefineMap.extend('passbolt.model.ActionLog', { 25 | id: 'string', 26 | type: 'string', 27 | data: 'any', 28 | creator: User, 29 | created: 'string' 30 | }); 31 | DefineMap.setReference('ActionLog', ActionLog); 32 | ActionLog.List = DefineList.extend({'#': {Type: ActionLog}}); 33 | 34 | ActionLog.connection = connect([connectParse, connectDataUrl, connectConstructor, connectMap], { 35 | Map: ActionLog, 36 | List: ActionLog.List, 37 | url: { 38 | resource: '/', 39 | getListData: function(params) { 40 | params['api-version'] = 'v2'; 41 | return Ajax.request({ 42 | url: 'actionlog/resource/{foreignKey}.json', 43 | type: 'GET', 44 | params: params 45 | }); 46 | } 47 | } 48 | }); 49 | 50 | export default ActionLog; 51 | -------------------------------------------------------------------------------- /app/component/administration/users_directory/primary_menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.6.0 13 | */ 14 | import Button from 'passbolt-mad/component/button'; 15 | import Component from 'passbolt-mad/component/component'; 16 | import template from '../../../view/template/component/administration/users_directory/primary_menu.stache'; 17 | 18 | const PrimaryMenu = Component.extend('passbolt.component.administration.ldap.PrimaryMenu', /** @static */ { 19 | defaults: { 20 | template: template, 21 | settings: {} 22 | } 23 | 24 | }, /** @prototype */ { 25 | 26 | /** 27 | * @inheritdoc 28 | */ 29 | afterStart: function() { 30 | const disabled = this.options.settings ? !this.options.settings.isEnabled() : true; 31 | this.saveButton = new Button('#js-ldap-settings-save-button', {state: {disabled: true}}); 32 | this.saveButton.start(); 33 | this.testButton = new Button('#js-ldap-settings-test-button', {state: {disabled: disabled}}); 34 | this.testButton.start(); 35 | this.simulateButton = new Button('#js-ldap-settings-simulate-button', {state: {disabled: disabled}}); 36 | this.simulateButton.start(); 37 | this.synchronizeButton = new Button('#js-ldap-settings-synchronize-button', {state: {disabled: disabled}}); 38 | this.synchronizeButton.start(); 39 | } 40 | }); 41 | 42 | export default PrimaryMenu; 43 | -------------------------------------------------------------------------------- /app/component/user/groups_filter_sidebar_section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | import Group from '../../model/map/group'; 16 | import PeopleGroupsListComponent from '../group/people_groups_list'; 17 | 18 | import template from '../../view/template/component/user/groups_filter_sidebar_section.stache'; 19 | 20 | const GroupsFilterSidebarSectionComponent = Component.extend('passbolt.component.user.GroupsFilterSidebarSection', /** @static */ { 21 | 22 | defaults: { 23 | template: template, 24 | selectedGroups: new Group.List() 25 | } 26 | 27 | }, /** @prototype */ { 28 | 29 | /** 30 | * @inheritdoc 31 | */ 32 | afterStart: function() { 33 | const peopleGroupsList = new PeopleGroupsListComponent('#js_wsp_users_groups_list', { 34 | selectedGroups: this.options.selectedGroups 35 | }); 36 | peopleGroupsList.state.on('empty', (ev, empty) => this._onGroupListEmptyChange(empty)); 37 | peopleGroupsList.start(); 38 | }, 39 | 40 | /** 41 | * Observe when the component is empty / filled 42 | * @param {boolean} empty True if empty, false otherwise 43 | */ 44 | _onGroupListEmptyChange: function(empty) { 45 | this.state.empty = empty; 46 | } 47 | 48 | }); 49 | 50 | export default GroupsFilterSidebarSectionComponent; 51 | -------------------------------------------------------------------------------- /app/view/template/component/profile/profile.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |

    {{ __('Profile') }}

    5 |
    6 | 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 | 45 | 46 | 47 |
    {{ __('Name') }}{{ user.profile.first_name }} {{ user.profile.last_name }}
    {{ __('Role') }}{{ user.role.name }}
    {{ __('Modified') }}{{ getTimeAgo(user.profile.modified) }}
    {{ __('Created') }}{{ getTimeAgo(user.profile.created) }}
    {{ __('Public key') }} 42 | {{ user.gpgkey.key_id }} 43 |

    Note: Sorry, it is not possible to change your key at the moment.

    44 |
    48 |
    49 |
    50 |
    51 |
    52 | -------------------------------------------------------------------------------- /app/model/service/plugin/auth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SA (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.11.0 13 | */ 14 | import MadBus from 'passbolt-mad/control/bus'; 15 | import Plugin from '../../../util/plugin'; 16 | 17 | export default class AuthService { 18 | 19 | /** 20 | * Check if the user is authenticated 21 | * @param {object} options Optional parameters 22 | * - options.requestApi {bool}, get the status from the API, default true. 23 | * @return {Promise} 24 | */ 25 | static async isAuthenticated(options) { 26 | return await Plugin.request("passbolt.auth.is-authenticated", [options]); 27 | } 28 | 29 | /** 30 | * Logout the user 31 | * @return {Promise} 32 | */ 33 | static logout() { 34 | clearInterval(AuthService.checkAuthStatusLoopInterval); 35 | return Plugin.request('passbolt.plugin.auth.logout'); 36 | } 37 | 38 | /** 39 | * Start an invertval to check if the user is authenticated. 40 | * - In the case the user is logged out, trigger a passbolt.auth.logged-out event. 41 | */ 42 | static startCheckAuthStatusLoop() { 43 | AuthService.checkAuthStatusLoopInterval = setInterval(async () => { 44 | const isAuthenticated = await AuthService.isAuthenticated({ requestApi: false }); 45 | if (!isAuthenticated) { 46 | clearInterval(AuthService.checkAuthStatusLoopInterval); 47 | MadBus.trigger('auth_auto_logged_out'); 48 | } 49 | }, 1000); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/view/template/form/user/create.stache: -------------------------------------------------------------------------------- 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 | {{#if(isAdmin}} 28 |
    29 | 30 |
    31 | 32 | {{ __('This user is an administrator') }} 33 |
    34 | {{#if(action == 'create')}} 35 |
    {{ __('Note: Administrators can add and delete users. They can also create groups and assign group managers. Admin can not see all passwords.') }}
    36 | {{/if}} 37 |
    38 | {{/if}} 39 |
    40 | 41 |
    42 | 43 | {{ __('cancel')}} 44 |
    45 | -------------------------------------------------------------------------------- /app/view/template/form/comment/add.stache: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/component/dialog/progress.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | */ 13 | import $ from 'jquery'; 14 | import DialogComponent from 'passbolt-mad/component/dialog'; 15 | import HtmlHelper from 'passbolt-mad/helper/html'; 16 | // eslint-disable-next-line no-unused-vars 17 | import I18n from 'passbolt-mad/util/lang/i18n'; 18 | import progressTemplate from '../../view/template/component/dialog/progress.stache'; 19 | 20 | const ProgressDialog = DialogComponent.extend('passbolt.component.ProgressDialog', /** @static */ { 21 | 22 | defaults: { 23 | label: 'Progress dialog component', 24 | template: progressTemplate 25 | }, 26 | 27 | /** 28 | * Instantiate a new Dialog. 29 | * 30 | * @param {Object} [options] option values for the component. These get added to 31 | * this.options and merged with defaults static variable 32 | * @return {Dialog} 33 | */ 34 | instantiate: function(options) { 35 | // Create the DOM entry point for the dialog 36 | let refElt = $('body'); 37 | let position = 'first'; 38 | 39 | // If a dialog already exist, position the new one right after. 40 | const $existingDialog = $('.dialog-wrapper:last'); 41 | if ($existingDialog.length) { 42 | refElt = $existingDialog; 43 | position = "after"; 44 | } 45 | 46 | // Insert the element in the page DOM. 47 | const $el = HtmlHelper.create(refElt, position, '
    '); 48 | 49 | return new ProgressDialog($el[0], options); 50 | } 51 | 52 | }, /** @prototype */ { 53 | 54 | }); 55 | 56 | export default ProgressDialog; 57 | -------------------------------------------------------------------------------- /app/form/resource/edit_description.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Feedback from 'passbolt-mad/form/feedback'; 15 | import Form from 'passbolt-mad/form/form'; 16 | import Textbox from 'passbolt-mad/form/element/textbox'; 17 | 18 | import template from '../../view/template/form/resource/edit_description.stache'; 19 | 20 | const EditDescriptionForm = Form.extend('passbolt.form.resource.EditDescription', /** @static */ { 21 | 22 | defaults: { 23 | template: template 24 | } 25 | 26 | }, /** @prototype */ { 27 | 28 | /** 29 | * @inheritdoc 30 | */ 31 | afterStart: function() { 32 | // Resource id 33 | const idSelector = `#${this.element.id} .js_resource_id`; 34 | const idOptions = { 35 | modelReference: 'Resource.id', 36 | value: this.options.data.Resource.id 37 | }; 38 | const idTextbox = new Textbox(idSelector, idOptions); 39 | this.addElement(idTextbox).start(); 40 | 41 | // Description 42 | const descriptionSelector = `#${this.element.id} .js_resource_description`; 43 | const descriptionOptions = { 44 | modelReference: 'Resource.description', 45 | value: this.options.data.Resource.description 46 | }; 47 | const descriptionTextbox = new Textbox(descriptionSelector, descriptionOptions).start(); 48 | const descriptionFeedback = new Feedback(`#${this.element.id} .js_resource_description_feedback`).start(); 49 | this.addElement(descriptionTextbox, descriptionFeedback); 50 | } 51 | }); 52 | 53 | export default EditDescriptionForm; 54 | -------------------------------------------------------------------------------- /app/model/filter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | 15 | class Filter { 16 | /** 17 | * Constructor 18 | * @param options 19 | */ 20 | constructor(options) { 21 | Object.assign(this, { 22 | id: '', 23 | type: '', 24 | forceReload: false, 25 | label: '', 26 | rules: {}, 27 | order: {} 28 | }, options); 29 | } 30 | 31 | /** 32 | * Get the order. 33 | * @returns {*} 34 | */ 35 | getOrders() { 36 | if (this.order) { 37 | return this.order; 38 | } 39 | return []; 40 | } 41 | 42 | /** 43 | * Get a rule. 44 | * @param name {string} The rule name 45 | * @return {mixed} The rule value 46 | */ 47 | getRule(name) { 48 | return this.rules[name]; 49 | } 50 | 51 | /** 52 | * Set a new rule, or change an existing rule value. 53 | * @param name {string} The rule name 54 | * @param value {mixed} The rule value 55 | */ 56 | setRule(name, value) { 57 | this.rules[name] = value; 58 | } 59 | 60 | /** 61 | * Get filters. 62 | * @param excludedRules {array} The rules to exclude 63 | * @return {object} Return the data that compose this filter 64 | */ 65 | getRules(excludedRules) { 66 | const returnValue = {}; 67 | excludedRules = excludedRules || []; 68 | 69 | for (const ruleName in this.rules) { 70 | if (excludedRules.indexOf(ruleName) == -1) { 71 | returnValue[ruleName] = this.rules[ruleName]; 72 | } 73 | } 74 | 75 | return returnValue; 76 | } 77 | } 78 | 79 | export default Filter; 80 | -------------------------------------------------------------------------------- /app/view/template/form/user/delete_transfer_permissions.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | You are about to delete {{user.profile.fullName()}}. 4 |

    5 |

    6 | This user is the owner of passwords or groups. 7 | You need to transfer the ownership to other users to continue. 8 |

    9 |
    10 |
    11 | {{#if(groups.length)}} 12 |

    Groups

    13 |
      14 | {{#each(groups)}} 15 |
    • 16 |
      17 | 18 | 19 |
      20 |
    • 21 | {{/each}} 22 |
    23 | {{/if}} 24 | {{#if(folders.length)}} 25 |

    Folders

    26 |
      27 | {{#each(folders)}} 28 |
    • 29 |
      30 | 31 | 32 |
      33 |
    • 34 | {{/each}} 35 |
    36 | {{/if}} 37 | {{#if(resources.length)}} 38 |

    Passwords

    39 |
      40 | {{#each(resources)}} 41 |
    • 42 |
      43 | 44 | 45 |
      46 |
    • 47 | {{/each}} 48 |
    49 | {{/if}} 50 |
    51 | 52 |
    53 | 54 | {{ __('cancel')}} 55 |
    56 | -------------------------------------------------------------------------------- /app/view/template/component/activity/resource_activity_item.stache: -------------------------------------------------------------------------------- 1 | {{{{ mappedItem.creatorName }} {{mappedItem.label}} {{mappedItem.resource.name}}
    3 |
    {{ getTimeAgo(mappedItem.created) }}
    4 | {{/displayUserAction}} 5 | 6 | {{displayPermissionsDetails}} 10 | {{/case}} 11 | {{/switch}} 12 | {{/displayDetails}} 13 | 14 | {{ 16 | {{#each(mappedItem.data.added)}} 17 |
  • {{>displayPermission}}
  • 18 | {{/each}} 19 | {{#each(mappedItem.data.updated)}} 20 |
  • {{>displayPermission}}
  • 21 | {{/each}} 22 | {{#each(mappedItem.data.removed)}} 23 |
  • {{>displayPermission}}
  • 24 | {{/each}} 25 | 26 | {{/displayPermissionsDetails}} 27 | 28 | {{ 30 | 31 | 32 |
    33 | {{full_name}} 34 | - {{type_human_readable}} 35 |
    36 |
    37 | {{#switch(action_type)}} 38 | {{#case('created')}} 39 | new 40 | {{/case}} 41 | {{#case('updated')}} 42 | updated 43 | {{/case}} 44 | {{#case('removed')}} 45 | deleted 46 | {{/case}} 47 | {{/switch}} 48 |
    49 | {{/displayPermission}} 50 | 51 |
  • 52 |
    53 |
    54 | {{>displayUserAction}} 55 | {{>displayDetails}} 56 |
    57 |
    58 |
    59 | activity author picture 60 |
    61 |
  • -------------------------------------------------------------------------------- /app/view/component/user/grid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import DomData from 'can-dom-data'; 15 | import domEvents from 'can-dom-events'; 16 | import GridView from 'passbolt-mad/view/component/grid'; 17 | 18 | const UserGridView = GridView.extend('passbolt.view.component.user.Grid', /** @static */ { 19 | 20 | }, /** @prototype */ { 21 | 22 | /** 23 | * Right click has been detected. (contextual menu). 24 | * we just stop the event here, as we do not want to base our contextual menu on this event, but on the mouse down event instead. 25 | * @event item_right_selected 26 | * @param {HTMLElement} el The element the event occurred on 27 | * @param {HTMLEvent} ev The event which occurred 28 | * @return {bool} 29 | */ 30 | '{element} tbody tr contextmenu': function(el, ev) { 31 | ev.stopPropagation(); 32 | ev.preventDefault(); 33 | return false; 34 | }, 35 | 36 | /** 37 | * Right click has been detected. (contextual menu). 38 | * @event item_right_selected 39 | * @param {HTMLElement} el The element the event occurred on 40 | * @param {HTMLEvent} ev The event which occurred 41 | * @return {bool} 42 | */ 43 | '{element} tbody tr mousedown': function(el, ev) { 44 | ev.stopPropagation(); 45 | ev.preventDefault(); 46 | if (ev.which == 3) { 47 | const itemClass = this.getController().getItemClass(); 48 | const item = DomData.get(el, itemClass.shortName); 49 | domEvents.dispatch(this.element, {type: 'item_right_selected', data: {item: item, srcEv: ev}}); 50 | } 51 | return false; 52 | } 53 | }); 54 | 55 | export default UserGridView; 56 | -------------------------------------------------------------------------------- /app/component/password/groups_filter_sidebar_section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Group from '../../model/map/group'; 15 | import PasswordCategoriesGroupsList from '../group/password_categories_groups_list'; 16 | import PrimarySidebarSectionComponent from '../workspace/primary_sidebar_section'; 17 | import User from '../../model/map/user'; 18 | 19 | import template from '../../view/template/component/password/groups_filter_sidebar_section.stache'; 20 | 21 | const GroupsFilterSidebarSectionComponent = PrimarySidebarSectionComponent.extend('passbolt.component.password.GroupsFilterSidebarSection', /** @static */ { 22 | 23 | defaults: { 24 | template: template, 25 | selectedGroups: new Group.List(), 26 | state: {hidden: true} 27 | } 28 | 29 | }, /** @prototype */ { 30 | 31 | /** 32 | * @inheritdoc 33 | */ 34 | afterStart: function() { 35 | const groupList = new PasswordCategoriesGroupsList('#js_wsp_password_categories_groups_list', { 36 | selectedGroups: this.options.selectedGroups, 37 | defaultGroupFilter: { 38 | 'has-users': User.getCurrent().id 39 | } 40 | }); 41 | this.groupList = groupList; 42 | groupList.state.on('loaded', (ev, loaded) => this._onGroupListLoadedChange(loaded)); 43 | groupList.start(); 44 | this._super(); 45 | }, 46 | 47 | /** 48 | * @inheritdoc 49 | */ 50 | _onGroupListLoadedChange: function(loaded) { 51 | if (loaded) { 52 | const isEmpty = this.groupList.options.items.length == 0; 53 | this.state.hidden = isEmpty; 54 | } 55 | } 56 | }); 57 | 58 | export default GroupsFilterSidebarSectionComponent; 59 | -------------------------------------------------------------------------------- /app/model/map/theme.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Ajax from '../../net/ajax'; 15 | import Config from 'passbolt-mad/config/config'; 16 | import connect from 'can-connect'; 17 | import connectDataUrl from 'can-connect/data/url/url'; 18 | import connectParse from 'can-connect/data/parse/parse'; 19 | import connectConstructor from 'can-connect/constructor/constructor'; 20 | import connectMap from 'can-connect/can/map/map'; 21 | import DefineList from 'passbolt-mad/model/list/list'; 22 | import DefineMap from 'passbolt-mad/model/map/map'; 23 | 24 | const Theme = DefineMap.extend('passbolt.model.Theme', { 25 | id: 'string', 26 | name: 'string', 27 | preview: 'string' 28 | }); 29 | DefineMap.setReference('Theme', Theme); 30 | Theme.List = DefineList.extend({'#': {Type: Theme}}); 31 | 32 | /** 33 | * Select a theme 34 | * @param {Theme} theme The target theme 35 | */ 36 | Theme.select = function(theme) { 37 | return Ajax.request({ 38 | url: '/account/settings/themes.json', 39 | type: 'POST', 40 | params: {value: theme.name} 41 | }).then(() => { 42 | Config.write('accountSetting.theme', theme.name); 43 | }); 44 | }; 45 | 46 | Theme.connection = connect([connectParse, connectDataUrl, connectConstructor, connectMap], { 47 | Map: Theme, 48 | List: Theme.List, 49 | url: { 50 | resource: '/', 51 | getListData: function(params) { 52 | params = params || {}; 53 | params['api-version'] = 'v2'; 54 | return Ajax.request({ 55 | url: '/account/settings/themes.json', 56 | type: 'GET', 57 | params: params 58 | }); 59 | } 60 | } 61 | }); 62 | 63 | export default Theme; 64 | -------------------------------------------------------------------------------- /app/component/user/primary_sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import GroupsFilterSidebarSectionComponent from '../user/groups_filter_sidebar_section'; 15 | import PrimarySidebarAbstractComponent from '../workspace/primary_sidebar'; 16 | import ShortcutsFilterSidebarSectionComponent from '../user/shortcuts_filter_sidebar_section'; 17 | 18 | import template from '../../view/template/component/user/primary_sidebar.stache'; 19 | 20 | const PrimarySidebarComponent = PrimarySidebarAbstractComponent.extend('passbolt.component.user.PrimarySidebar', /** @static */ { 21 | 22 | defaults: { 23 | label: 'User Workspace Primary Sidebar', 24 | template: template, 25 | defaultFilter: null, 26 | selectedGroups: null 27 | } 28 | 29 | }, /** @prototype */ { 30 | 31 | /** 32 | * @inheritdoc 33 | */ 34 | afterStart: function() { 35 | this._initShortcutsFilterSection(); 36 | this._initGroupsFilterSection(); 37 | this._super(); 38 | }, 39 | 40 | /** 41 | * Initialize the shortcuts filter section 42 | */ 43 | _initShortcutsFilterSection: function() { 44 | const component = new ShortcutsFilterSidebarSectionComponent('#js_wsp_users_filter_shortcuts', { 45 | allFilter: this.options.defaultFilter 46 | }); 47 | component.start(); 48 | }, 49 | 50 | /** 51 | * Initialize the groups filter section 52 | */ 53 | _initGroupsFilterSection: function() { 54 | const component = new GroupsFilterSidebarSectionComponent('#js_wsp_users_groups', { 55 | selectedGroups: this.options.selectedGroups 56 | }); 57 | component.start(); 58 | } 59 | 60 | }); 61 | 62 | export default PrimarySidebarComponent; 63 | -------------------------------------------------------------------------------- /app/component/workspace/secondary_sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import Component from 'passbolt-mad/component/component'; 16 | import MadBus from 'passbolt-mad/control/bus'; 17 | import Config from 'passbolt-mad/config/config'; 18 | 19 | import template from '../../view/template/component/workspace/secondary_sidebar.stache'; 20 | 21 | const SecondarySidebarComponent = Component.extend('passbolt.component.workspace.SecondarySidebar', /** @static */ { 22 | 23 | defaults: { 24 | label: 'Sidebar Component', 25 | template: template 26 | } 27 | 28 | }, /** @prototype */ { 29 | 30 | /** 31 | * Set the title 32 | * @param {string} title The new title 33 | */ 34 | setTitle: function(title) { 35 | $('.sidebar .sidebar-header .sidebar-header-title', this.element).text(title); 36 | }, 37 | 38 | /** 39 | * Set the subtitle 40 | * @param {string} subtitle The new subtitle 41 | */ 42 | setSubtitle: function(subtitle) { 43 | $('.sidebar .sidebar-header .sidebar-header-subtitle', this.element).text(subtitle); 44 | }, 45 | 46 | /** 47 | * Observe when the workspace sidebar setting change. 48 | */ 49 | '{mad.bus.element} workspace_sidebar_state_change': function() { 50 | if (!Config.read('ui.workspace.showSidebar')) { 51 | this.destroyAndRemove(); 52 | } 53 | }, 54 | 55 | /** 56 | * Observe when the user clicks on the close button 57 | */ 58 | '{element} .js_sidebar_close click': function() { 59 | Config.write('ui.workspace.showSidebar', false); 60 | MadBus.trigger('workspace_sidebar_state_change'); 61 | } 62 | 63 | }); 64 | 65 | export default SecondarySidebarComponent; 66 | -------------------------------------------------------------------------------- /app/model/map/permission_type.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import DefineMap from 'passbolt-mad/model/map/map'; 15 | // eslint-disable-next-line no-unused-vars 16 | import I18n from 'passbolt-mad/util/lang/i18n'; 17 | 18 | const PermissionType = DefineMap.extend('passbolt.model.PermissionType', { 19 | serial: 'string', 20 | name: 'string', 21 | description: 'string' 22 | }); 23 | 24 | /** 25 | * The permission type read. 26 | * @type {number} 27 | */ 28 | PermissionType.READ = 1; 29 | /** 30 | * The permission type update. 31 | * @type {number} 32 | */ 33 | PermissionType.UPDATE = 7; 34 | /** 35 | * The permission type admin. 36 | * @type {number} 37 | */ 38 | PermissionType.ADMIN = 15; 39 | 40 | /** 41 | * Translation of the available permissions types. 42 | */ 43 | PermissionType.PERMISSION_TYPES = { 44 | 1: __('read'), 45 | 7: __('update'), 46 | 15: __('owner') 47 | }; 48 | 49 | /** 50 | * @inheritdoc 51 | */ 52 | PermissionType.validationRules = { 53 | serial: [{ 54 | rule: 'choice', 55 | options: { 56 | callback: function() { 57 | // return the available serials (array_keys in js style) 58 | return $.map(PermissionType.PERMISSION_TYPES, (element, index) => index); 59 | } 60 | } 61 | }] 62 | }; 63 | 64 | /** 65 | * Get permission type formated. 66 | * @return {string} 67 | */ 68 | PermissionType.formatToString = function(permId) { 69 | switch (permId.toString()) { 70 | case PermissionType.ADMIN.toString(): 71 | return __('is %s', PermissionType.PERMISSION_TYPES[permId]); 72 | default: 73 | return __('can %s', PermissionType.PERMISSION_TYPES[permId]); 74 | } 75 | }; 76 | 77 | export default PermissionType; 78 | -------------------------------------------------------------------------------- /app/component/profile/profile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | import MadBus from 'passbolt-mad/control/bus'; 16 | import template from '../../view/template/component/profile/profile.stache'; 17 | 18 | const ProfileComponent = Component.extend('passbolt.component.profile.Profile', /** @static */ { 19 | 20 | defaults: { 21 | template: template, 22 | user: null 23 | } 24 | 25 | }, /** @prototype */ { 26 | 27 | /** 28 | * Before render. 29 | */ 30 | 'beforeRender': function() { 31 | this._super(); 32 | this.setViewData('user', this.options.user); 33 | }, 34 | 35 | /* ************************************************************** */ 36 | /* LISTEN TO THE MODEL EVENTS */ 37 | /* ************************************************************** */ 38 | 39 | /** 40 | * Observe when the user is updated 41 | */ 42 | '{user} updated': function() { 43 | this.refresh(); 44 | }, 45 | 46 | /* ************************************************************** */ 47 | /* LISTEN TO THE APP EVENTS */ 48 | /* ************************************************************** */ 49 | 50 | /** 51 | * The user want to edit his personal information 52 | */ 53 | '{element} .edit-action click': function() { 54 | const user = this.options.user; 55 | MadBus.trigger('request_profile_edition', {user: user}); 56 | }, 57 | 58 | /** 59 | * The user want to edit his avatar 60 | */ 61 | '{element} .edit-avatar-action click': function() { 62 | const user = this.options.user; 63 | MadBus.trigger('request_profile_avatar_edition', {user: user}); 64 | } 65 | }); 66 | 67 | export default ProfileComponent; 68 | -------------------------------------------------------------------------------- /app/view/template/component/password/password_secondary_sidebar.stache: -------------------------------------------------------------------------------- 1 | 44 | 45 | -------------------------------------------------------------------------------- /app/model/map/accountSetting.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Ajax from '../../net/ajax'; 15 | import Config from 'passbolt-mad/config/config'; 16 | import connect from 'can-connect'; 17 | import connectDataUrl from 'can-connect/data/url/url'; 18 | import connectParse from 'can-connect/data/parse/parse'; 19 | import connectConstructor from 'can-connect/constructor/constructor'; 20 | import connectMap from 'can-connect/can/map/map'; 21 | import DefineList from 'passbolt-mad/model/list/list'; 22 | import DefineMap from 'passbolt-mad/model/map/map'; 23 | 24 | const AccountSetting = DefineMap.extend('passbolt.model.AccountSetting', { 25 | id: 'string', 26 | user_id: 'string', 27 | property_id: 'string', 28 | property: 'string', 29 | value: 'string' 30 | }); 31 | DefineMap.setReference('AccountSetting', AccountSetting); 32 | AccountSetting.List = DefineList.extend({'#': {Type: AccountSetting}}); 33 | 34 | /** 35 | * Store the account settings in the config. 36 | * @param accountSettings 37 | */ 38 | AccountSetting.saveInConfig = function(accountSettings) { 39 | accountSettings.forEach(accountSetting => { 40 | Config.write(`accountSetting.${accountSetting.property}`, accountSetting.value); 41 | }); 42 | }; 43 | 44 | AccountSetting.connection = connect([connectParse, connectDataUrl, connectConstructor, connectMap], { 45 | Map: AccountSetting, 46 | List: AccountSetting.List, 47 | url: { 48 | resource: '/', 49 | getListData: function(params) { 50 | params = params || {}; 51 | params['api-version'] = 'v2'; 52 | return Ajax.request({ 53 | url: '/account/settings.json', 54 | type: 'GET', 55 | params: params 56 | }); 57 | } 58 | } 59 | }); 60 | 61 | export default AccountSetting; 62 | -------------------------------------------------------------------------------- /app/model/map/group_delete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import DefineMap from 'passbolt-mad/model/map/map'; 15 | import getObject from 'can-util/js/get/get'; 16 | import Group from './group'; 17 | import Resource from './resource'; 18 | 19 | const GroupDelete = DefineMap.extend('passbolt.model.GroupDelete', { 20 | group_id: 'string', 21 | groups_to_delete: Group.List, 22 | errors: { 23 | type: { 24 | resources: { 25 | type: { 26 | sole_owner: "array" 27 | } 28 | }, 29 | folders: { 30 | type: { 31 | sole_owner: "array" 32 | } 33 | } 34 | } 35 | }, 36 | 37 | /** 38 | * Get the resources to transfer the owner for. 39 | * @return {Resource.List} 40 | */ 41 | getResourcesToTransferOwner: function() { 42 | const resourcesSoleOwner = getObject(this, 'errors.resources.sole_owner') || []; 43 | let resources = new Resource.List(resourcesSoleOwner); 44 | resources = resources.sort((a, b) => a.name > b.name); 45 | resources.forEach(resource => { 46 | resource.permissions = resource.permissions.filter(permission => permission.aro_foreign_key != this.group_id); 47 | }); 48 | 49 | return resources; 50 | }, 51 | 52 | /** 53 | * Get the folders to transfer the owner for. 54 | * @return {array} 55 | */ 56 | getFoldersToTransferOwner: function() { 57 | let folders = getObject(this, 'errors.folders.sole_owner') || []; 58 | folders = folders.sort((a, b) => a.name > b.name); 59 | folders.forEach(folder => { 60 | folder.permissions = folder.permissions.filter(permission => permission.aro_foreign_key != this.group_id); 61 | }); 62 | 63 | return folders; 64 | } 65 | 66 | }); 67 | 68 | export default GroupDelete; 69 | -------------------------------------------------------------------------------- /app/model/service/plugin/group.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SA (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.11.0 13 | */ 14 | import Plugin from '../../../util/plugin'; 15 | 16 | export default class GroupService { 17 | /** 18 | * Request the plugin to insert the group edit iframe 19 | * @param {string} groupId The target group id 20 | * @param {boolean} canAddGroupUsers Is the current user can add members to this group 21 | */ 22 | static insertGroupEditframe(groupId, canAddGroupUsers) { 23 | Plugin.send('passbolt.plugin.group_edit', {groupId: groupId, canAddGroupUsers: canAddGroupUsers}); 24 | } 25 | 26 | /** 27 | * Request the plugin to edit a group user 28 | * @param {GroupUser} groupUdataser The group user to remove 29 | */ 30 | static groupEditIframeEditGroupUser(data) { 31 | const groupUser = { 32 | id: data.id, 33 | user_id: data.user_id, 34 | group_id: data.group_id, 35 | is_admin: data.is_admin, 36 | is_new: data.is_new 37 | }; 38 | Plugin.send('passbolt.group.edit.edit_group_user', {groupUser: groupUser}); 39 | } 40 | 41 | /** 42 | * Request the plugin to remove a group user 43 | * @param {GroupUser} data The group user to remove 44 | */ 45 | static groupEditIframeRemoveGroupUser(data) { 46 | const groupUser = { 47 | id: data.id, 48 | user_id: data.user_id, 49 | group_id: data.group_id, 50 | is_admin: data.is_admin, 51 | is_new: data.is_new || false 52 | }; 53 | Plugin.send('passbolt.group.edit.remove_group_user', {groupUser: groupUser}); 54 | } 55 | 56 | /** 57 | * Request the plugin to save the group 58 | * @param {Object} group The group to save 59 | */ 60 | static groupEditIframeSave(group) { 61 | Plugin.send('passbolt.group.edit.save', {group: group}); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/model/map/role.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Ajax from '../../net/ajax'; 15 | import connect from 'can-connect'; 16 | import connectDataUrl from 'can-connect/data/url/url'; 17 | import connectParse from 'can-connect/data/parse/parse'; 18 | import connectConstructor from 'can-connect/constructor/constructor'; 19 | import connectMap from 'can-connect/can/map/map'; 20 | import DefineList from 'passbolt-mad/model/list/list'; 21 | import DefineMap from 'passbolt-mad/model/map/map'; 22 | 23 | const Role = DefineMap.extend('passbolt.model.Role', { 24 | id: 'string', 25 | name: 'string' 26 | }); 27 | DefineMap.setReference('Role', Role); 28 | Role.List = DefineList.extend({'#': {Type: Role}}); 29 | 30 | /** 31 | * Get the stored roles. 32 | * @returns {DefineList} 33 | */ 34 | Role.getCache = function() { 35 | return this.cache; 36 | }; 37 | 38 | /** 39 | * Put the roles in cache 40 | * @param {DefineList} roles 41 | */ 42 | Role.setCache = function(roles) { 43 | this.cache = roles; 44 | }; 45 | 46 | /** 47 | * Get role id from name. 48 | * @param {string} roleName 49 | */ 50 | Role.toId = function(roleName) { 51 | return this.cache.reduce((carry, item) => { 52 | if (roleName == item.name) { 53 | carry = item.id; 54 | } 55 | return carry; 56 | }, ''); 57 | }; 58 | 59 | Role.connection = connect([connectParse, connectDataUrl, connectConstructor, connectMap], { 60 | Map: Role, 61 | List: Role.List, 62 | url: { 63 | resource: '/', 64 | getListData: function(params) { 65 | params = params || {}; 66 | params['api-version'] = 'v2'; 67 | return Ajax.request({ 68 | url: 'roles.json', 69 | type: 'GET', 70 | params: params 71 | }); 72 | } 73 | } 74 | }); 75 | 76 | export default Role; 77 | -------------------------------------------------------------------------------- /app/view/component/group/edit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import DomData from 'can-dom-data'; 16 | import domEvents from 'can-dom-events'; 17 | import View from 'passbolt-mad/view/view'; 18 | 19 | const EditView = View.extend('passbolt.view.component.group.Edit', /** @static */ { }, /** @prototype */ { 20 | 21 | /* ************************************************************** */ 22 | /* LISTEN TO VIEW EVENTS */ 23 | /* ************************************************************** */ 24 | 25 | /** 26 | * Observe when the user want to delete a groupUser. 27 | * @param {HTMLElement} el The element the event occurred on 28 | * @param {HTMLEvent} ev The event which occurred 29 | */ 30 | '{element} .js_group_user_delete click': function(el, ev) { 31 | ev.stopPropagation(); 32 | ev.preventDefault(); 33 | const $li = $(el).parents('li'); 34 | const groupUser = DomData.get($li[0], 'passbolt.model.GroupUser'); 35 | domEvents.dispatch(this.element, {type: 'request_group_user_delete', data: {groupUser: groupUser}}); 36 | }, 37 | 38 | /** 39 | * Observe when the user want to edit a permission type. 40 | * @param {HTMLElement} el The element the event occurred on 41 | * @param {HTMLEvent} ev The event which occurred 42 | */ 43 | '{element} .js_group_user_is_admin changed': function(el, ev) { 44 | ev.stopPropagation(); 45 | ev.preventDefault(); 46 | const data = ev.data; 47 | const $li = $(el).parents('li'); 48 | const groupUser = DomData.get($li[0], 'passbolt.model.GroupUser'); 49 | const isAdmin = data.value; 50 | domEvents.dispatch(this.element, {type: 'request_group_user_edit', data: {groupUser: groupUser, isAdmin: isAdmin}}); 51 | } 52 | 53 | }); 54 | 55 | export default EditView; 56 | -------------------------------------------------------------------------------- /app/component/group/password_categories_groups_list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Filter from '../../model/filter'; 15 | import Group from '../../model/map/group'; 16 | import GroupsListComponent from '../group/groups_list'; 17 | import GroupsListView from '../../view/component/group/groups_list'; 18 | // eslint-disable-next-line no-unused-vars 19 | import I18n from 'passbolt-mad/util/lang/i18n'; 20 | import MadBus from 'passbolt-mad/control/bus'; 21 | 22 | import itemTemplate from '../../view/template/component/group/group_item.stache'; 23 | 24 | const PasswordCategoriesGroupsList = GroupsListComponent.extend('passbolt.component.PasswordCategoriesGroupsList', /** @static */ { 25 | 26 | defaults: { 27 | itemClass: Group, 28 | itemTemplate: itemTemplate, 29 | prefixItemId: 'group_', 30 | selectedGroups: new Group.List(), 31 | selectedFilter: null, 32 | viewClass: GroupsListView 33 | } 34 | 35 | }, /** @prototype */ { 36 | 37 | /* ************************************************************** */ 38 | /* LISTEN TO THE APP EVENTS */ 39 | /* ************************************************************** */ 40 | 41 | /** 42 | * Filter the workspace by group. 43 | * @param {passbolt.model.Group} group The group to filter the workspace with 44 | */ 45 | _filterWorkspaceByGroup: function(group) { 46 | this.selectedFilter = new Filter({ 47 | id: `workspace_filter_group_${group.id}`, 48 | type: 'group', 49 | label: __('%s (group)', group.name), 50 | rules: { 51 | 'is-shared-with-group': group.id 52 | }, 53 | order: ['Resource.modified DESC'] 54 | }); 55 | MadBus.trigger('filter_workspace', {filter: this.selectedFilter}); 56 | } 57 | 58 | }); 59 | 60 | export default PasswordCategoriesGroupsList; 61 | -------------------------------------------------------------------------------- /app/component/session/session_expired.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | import template from '../../view/template/component/session/session_expired.stache'; 16 | 17 | const SessionExpiredComponent = Component.extend('passbolt.component.session.SessionExpired', /** @static */ { 18 | 19 | defaults: { 20 | label: 'Session Expired Controller', 21 | template: template, 22 | timeToRedirect: 5000, 23 | countDownInterval: null 24 | } 25 | 26 | }, /** @prototype */ { 27 | 28 | /** 29 | * @inheritdoc 30 | */ 31 | afterStart: function() { 32 | const initialTime = new Date().getTime(); 33 | 34 | // Check every second if the time to wait before redirection has been consumed. 35 | this.options.countDownInterval = setInterval(() => { 36 | const elapsedTime = new Date().getTime() - initialTime; 37 | if (elapsedTime > this.options.timeToRedirect) { 38 | clearInterval(this.options.countDownInterval); 39 | location.href = APP_URL; 40 | } 41 | }, 1000); 42 | }, 43 | 44 | /** 45 | * The session expired component has been destroyed. 46 | */ 47 | destroy: function() { 48 | if (this.options.countDownInterval != null) { 49 | clearInterval(this.options.countDownInterval); 50 | } 51 | }, 52 | 53 | /* ************************************************************** */ 54 | /* LISTEN TO THE VIEW EVENTS */ 55 | /* ************************************************************** */ 56 | 57 | /** 58 | * The user clicked on the Redirect now button 59 | */ 60 | ' .submit-wrapper input click': function() { 61 | clearInterval(this.options.countDownInterval); 62 | location.href = APP_URL; 63 | } 64 | }); 65 | 66 | export default SessionExpiredComponent; 67 | -------------------------------------------------------------------------------- /app/component/mfa/mfa_required.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.4.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | import template from '../../view/template/component/mfa/mfa_required.stache'; 16 | 17 | const MfaRequiredComponent = Component.extend('passbolt.component.mfa.MfaRequired', /** @static */ { 18 | 19 | defaults: { 20 | label: 'Multi Factor Authentication Expired Controller', 21 | url: null, 22 | template: template, 23 | timeToRedirect: 5000, 24 | countDownInterval: null 25 | } 26 | 27 | }, /** @prototype */ { 28 | 29 | /** 30 | * @inheritdoc 31 | */ 32 | afterStart: function() { 33 | const initialTime = new Date().getTime(); 34 | 35 | // Check every second if the time to wait before redirection has been consumed. 36 | this.options.countDownInterval = setInterval(() => { 37 | const elapsedTime = new Date().getTime() - initialTime; 38 | if (elapsedTime > this.options.timeToRedirect) { 39 | clearInterval(this.options.countDownInterval); 40 | location.href = APP_URL + this.options.url; 41 | } 42 | }, 1000); 43 | }, 44 | 45 | /** 46 | * The mfa required component has been destroyed. 47 | */ 48 | destroy: function() { 49 | if (this.options.countDownInterval != null) { 50 | clearInterval(this.options.countDownInterval); 51 | } 52 | }, 53 | 54 | /* ************************************************************** */ 55 | /* LISTEN TO THE VIEW EVENTS */ 56 | /* ************************************************************** */ 57 | 58 | /** 59 | * The user clicked on the Redirect now button 60 | */ 61 | ' .submit-wrapper input click': function() { 62 | clearInterval(this.options.countDownInterval); 63 | location.href = APP_URL + this.options.url; 64 | } 65 | }); 66 | 67 | export default MfaRequiredComponent; 68 | -------------------------------------------------------------------------------- /app/view/template/component/password/information_sidebar_section.stache: -------------------------------------------------------------------------------- 1 | 4 | 5 |
      6 |
    • 7 | {{ __('Username') }} 8 | {{ resource.username }} 9 |
    • 10 |
    • 11 |
      {{ __('Password') }}
      12 |
      13 |
      14 | 15 | copy password to clipboard 16 | 17 |
      {{ resource.secrets[0].data }}
      18 |
      19 |
      20 |
    • 21 |
    • 22 | {{ __('URL') }} 23 | 24 | {{#if(resource.safeUrl() != '')}} 25 | {{ resource.uri }} 26 | {{#else}} 27 | {{ resource.uri }} 28 | {{/if}} 29 | 30 |
    • 31 |
    • 32 | {{ __('Created') }} 33 | {{ getTimeAgo(resource._data.created) }} 34 |
    • 35 |
    • 36 | {{ __('Created by') }} 37 | {{ resource.creator.username }} 38 |
    • 39 |
    • 40 | {{ __('Last modified') }} 41 | {{ getTimeAgo(resource.modified) }} 42 |
    • 43 |
    • 44 | {{ __('Modified by') }} 45 | {{ resource.modifier.username }} 46 |
    • 47 | {{#if(pluginFoldersEnabled)}} 48 |
    • 49 | Location 50 | 51 | {{#if(folderParentName}} 52 | 53 | 54 | 55 | 56 | 57 | 58 | {{folderParentName}} 59 | 60 | {{/if}} 61 | 62 |
    • 63 | {{/if}} 64 |
    65 | -------------------------------------------------------------------------------- /app/component/comment/comments_list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import Comment from '../../model/map/comment'; 16 | import DomData from 'can-dom-data'; 17 | import MadBus from 'passbolt-mad/control/bus'; 18 | import MadMap from 'passbolt-mad/util/map/map'; 19 | import Tree from 'passbolt-mad/component/tree'; 20 | import User from '../../model/map/user'; 21 | 22 | import itemTemplate from '../../view/template/component/comment/comment_item.stache'; 23 | 24 | const CommentsListComponent = Tree.extend('passbolt.component.comment.CommentsList', /** @static */ { 25 | 26 | defaults: { 27 | label: 'Comments List Controller', 28 | itemClass: Comment, 29 | itemTemplate: itemTemplate 30 | } 31 | 32 | }, /** @prototype */ { 33 | 34 | /** 35 | * @inheritdoc 36 | */ 37 | init: function(el, options) { 38 | options.map = this._getMap(); 39 | this._super(el, options); 40 | }, 41 | 42 | /** 43 | * Get the map 44 | * 45 | * @return {UtilMap} 46 | */ 47 | _getMap: function() { 48 | return new MadMap({ 49 | id: 'id', 50 | content: 'content', 51 | modified: 'modified', 52 | creatorAvatarPath: { 53 | key: 'creator', 54 | func: creator => creator.profile.avatarPath('small') 55 | }, 56 | creatorName: { 57 | key: 'creator', 58 | func: creator => creator.profile.fullName() 59 | }, 60 | isOwner: { 61 | key: 'created_by', 62 | func: createdBy => createdBy == User.getCurrent().id 63 | } 64 | }); 65 | }, 66 | 67 | /** 68 | * Observe when the user clicks on the delete button for comment 69 | * @param {HTMLElement} el The element the event occurred on 70 | * @param {HTMLEvent} ev The event which occurred 71 | */ 72 | '{element} .actions a.js_delete_comment click': function(el, ev) { 73 | ev.stopPropagation(); 74 | ev.preventDefault(); 75 | const $li = $(el).parents('li.comment-wrapper'); 76 | const comment = DomData.get($li[0], Comment.shortName); 77 | MadBus.trigger('request_delete_comment', {comment: comment}); 78 | } 79 | }); 80 | 81 | export default CommentsListComponent; 82 | -------------------------------------------------------------------------------- /app/component/workspace/secondary_menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Component from 'passbolt-mad/component/component'; 15 | import Config from 'passbolt-mad/config/config'; 16 | import MadBus from 'passbolt-mad/control/bus'; 17 | import ToggleButton from 'passbolt-mad/component/toggle_button'; 18 | import template from '../../view/template/component/workspace/secondary_menu.stache'; 19 | 20 | const WorkspaceSecondaryMenu = Component.extend('passbolt.component.WorkspaceSecondaryMenu', /** @static */ { 21 | 22 | defaults: { 23 | label: 'Workspace Secondary Menu', 24 | template: template, 25 | tag: 'ul' 26 | } 27 | 28 | }, /** @prototype */ { 29 | 30 | /** 31 | * @inheritdoc 32 | */ 33 | afterStart: function() { 34 | const showSidebar = Config.read('ui.workspace.showSidebar'); 35 | const viewSidebarButton = new ToggleButton('#js_wk_secondary_menu_view_sidebar_button', { 36 | state: {selected: showSidebar} 37 | }); 38 | viewSidebarButton.start(); 39 | this.viewSidebarButton = viewSidebarButton; 40 | this.viewSidebarButton.state.on('selected', (ev, selected) => this._onViewSidebarSelectedChange(selected)); 41 | }, 42 | 43 | /** 44 | * Observe when the viewbar show/hide button selected property changed 45 | * @param {boolean} showSidebar Show / hide the sidebar 46 | * @private 47 | */ 48 | _onViewSidebarSelectedChange: function(showSidebar) { 49 | Config.write('ui.workspace.showSidebar', showSidebar); 50 | MadBus.trigger('workspace_sidebar_state_change'); 51 | }, 52 | 53 | /** 54 | * Observe when the workspace sidebar setting change. 55 | */ 56 | '{mad.bus.element} workspace_sidebar_state_change': function() { 57 | this.viewSidebarButton.state.selected = Config.read('ui.workspace.showSidebar'); 58 | }, 59 | 60 | /** 61 | * Observe when the user wants to view the side bar 62 | */ 63 | '{viewSidebarButton.element} click': function() { 64 | const showSidebar = !Config.read('ui.workspace.showSidebar'); 65 | Config.write('ui.workspace.showSidebar', showSidebar); 66 | MadBus.trigger('workspace_sidebar_state_change'); 67 | } 68 | }); 69 | 70 | export default WorkspaceSecondaryMenu; 71 | -------------------------------------------------------------------------------- /app/config/routes.js: -------------------------------------------------------------------------------- 1 | 2 | import $ from 'jquery'; 3 | import CanDefineMap from 'can-define/map/map'; 4 | import route from 'can-route'; 5 | import RoutePushstate from 'can-route-pushstate'; 6 | 7 | const AppViewModel = CanDefineMap.extend({ 8 | controller: 'string', 9 | action: 'string' 10 | }); 11 | const appState = new AppViewModel(); 12 | route.data = appState; 13 | route.urlData = new RoutePushstate(); 14 | const appUrl = new URL($('base').attr('href')); 15 | route.urlData.root = appUrl.pathname; 16 | 17 | // Administration routes 18 | route.register('/app/administration/users-directory/edit', {controller: 'Administration', action: 'usersDirectory/edit'}); 19 | route.register('/app/administration/users-directory', {controller: 'Administration', action: 'usersDirectory'}); 20 | route.register('/app/administration/mfa', {controller: 'Administration', action: 'mfa'}); 21 | route.register('/app/administration/email-notification', {controller: 'Administration', action: 'emailNotification'}); 22 | route.register('/app/administration', {controller: 'Administration', action: 'mfa'}); 23 | 24 | // Folders routes 25 | route.register('/app/folders/view/{id}', {controller: 'Password', action: 'viewFolder'}); 26 | 27 | // Groups routes 28 | route.register('/app/groups/delete/{id}', {controller: 'User', action: 'groupDelete'}); 29 | route.register('/app/groups/edit/{id}', {controller: 'User', action: 'groupEdit'}); 30 | route.register('/app/groups/view/{id}', {controller: 'User', action: 'groupView'}); 31 | route.register('/app/groups/view/{id}/membership', {controller: 'User', action: 'groupViewMembership'}); 32 | 33 | // Passwords routes 34 | route.register('/app/passwords/view/{id}', {controller: 'Password', action: 'view'}); 35 | route.register('/app/passwords', {controller: 'Password', action: 'index'}); 36 | 37 | // Users routes 38 | route.register('/app/users/add', {controller: 'User', action: 'add'}); 39 | route.register('/app/users/edit/{id}', {controller: 'User', action: 'edit'}); 40 | route.register('/app/users/delete/{id}', {controller: 'User', action: 'delete'}); 41 | route.register('/app/users/view/{id}', {controller: 'User', action: 'view'}); 42 | route.register('/app/users', {controller: 'User', action: 'index'}); 43 | 44 | // User settings routes 45 | route.register('/app/settings/keys', {controller: 'Settings', action: 'keys'}); 46 | route.register('/app/settings/profile', {controller: 'Settings', action: 'profile'}); 47 | route.register('/app/settings/theme', {controller: 'Settings', action: 'theme'}); 48 | route.register('/app/settings/mfa', {controller: 'Settings', action: 'mfa'}); 49 | route.register('/app/settings', {controller: 'Settings', action: 'profile'}); 50 | 51 | // Default route 52 | route.register('', {controller: 'Password', action: 'index'}); 53 | 54 | route.start(); 55 | -------------------------------------------------------------------------------- /app/view/component/permission/permissions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import $ from 'jquery'; 15 | import DomData from 'can-dom-data'; 16 | import domEvents from 'can-dom-events'; 17 | import View from 'passbolt-mad/view/view'; 18 | 19 | const PermissionsView = View.extend('passbolt.view.component.permission.Permissions', /** @static */ { }, /** @prototype */ { 20 | 21 | /* ************************************************************** */ 22 | /* LISTEN TO VIEW EVENTS */ 23 | /* ************************************************************** */ 24 | 25 | /** 26 | * Observe when the user want to delete a permission. 27 | * @param {HTMLElement} el The element the event occurred on 28 | * @param {HTMLEvent} ev The event which occurred 29 | */ 30 | '{element} .js_perm_delete click': function(el, ev) { 31 | ev.stopPropagation(); 32 | ev.preventDefault(); 33 | const $li = $(el).parents('li'); 34 | const permission = DomData.get($li[0], 'passbolt.model.Permission'); 35 | domEvents.dispatch(this.element, {type: 'request_permission_delete', data: {permission: permission}}); 36 | }, 37 | 38 | /** 39 | * Observe when the user want to edit a permission type. 40 | * @param {HTMLElement} el The element the event occurred on 41 | * @param {HTMLEvent} ev The event which occurred 42 | */ 43 | '{element} .js_share_rs_perm_type changed': function(el, ev) { 44 | ev.stopPropagation(); 45 | ev.preventDefault(); 46 | const data = ev.data; 47 | const $li = $(el).parents('li'); 48 | const permission = DomData.get($li[0], 'passbolt.model.Permission'); 49 | const type = data.value; 50 | domEvents.dispatch(this.element, {type: 'request_permission_edit', data: {permission: permission, type: type}}); 51 | }, 52 | 53 | /** 54 | * Observe when the user want to reset the filter 55 | * @param {HTMLElement} el The element the event occurred on 56 | * @param {HTMLEvent} ev The event which occurred 57 | */ 58 | '{element} #js_perm_create_form_add_btn click': function(el, ev) { 59 | ev.stopPropagation(); 60 | ev.preventDefault(); 61 | $(el).trigger('submit'); 62 | } 63 | 64 | }); 65 | 66 | export default PermissionsView; 67 | -------------------------------------------------------------------------------- /src/components/Common/UserAvatar/UserAvatar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) 2020 Passbolt SA (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) 2020 Passbolt SA (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.13.0 13 | */ 14 | import React, {Component} from "react"; 15 | import PropTypes from "prop-types"; 16 | import Config from "../../../legacy/config/config"; 17 | 18 | class UserAvatar extends Component { 19 | /** 20 | * Constructor 21 | * @param {Object} props 22 | */ 23 | constructor(props) { 24 | super(props); 25 | this.state = {error: false}; 26 | } 27 | 28 | /** 29 | * Return true if the user from props contains a valid profile with avatar url properties 30 | * @returns {boolean} 31 | */ 32 | propsHasUrl() { 33 | return this.props.user && 34 | this.props.user.profile && 35 | this.props.user.profile.avatar && 36 | this.props.user.profile.avatar.url && 37 | this.props.user.profile.avatar.url.small; 38 | } 39 | 40 | propsUrlHasProtocol() { 41 | return this.props.user.profile.avatar.url.small.startsWith('https://'); 42 | } 43 | 44 | formatUrl(url) { 45 | const trustedDomain = APP_URL; 46 | return `${trustedDomain}/${url}`; 47 | } 48 | 49 | getPropsUrl() { 50 | return this.props.user.profile.avatar.url.small; 51 | } 52 | 53 | getAvatarSrc() { 54 | if (!this.state.error && this.propsHasUrl()) { 55 | if (this.propsUrlHasProtocol()) { 56 | return this.getPropsUrl(); 57 | } else { 58 | return this.formatUrl(this.getPropsUrl()); 59 | } 60 | } 61 | return this.formatUrl('/img/avatar/user.png'); 62 | } 63 | 64 | handleError() { 65 | console.error(`Could not load avatar image url: ${this.getAvatarSrc()}`); 66 | this.setState({error: true}); 67 | } 68 | 69 | getAltText() { 70 | return `Avatar of user ${this.props.user.profile.first_name} ${this.props.user.profile.last_name}.`; 71 | } 72 | 73 | render() { 74 | return ( 75 |
    76 | {this.getAltText()}/ 77 |
    78 | ) 79 | } 80 | } 81 | 82 | UserAvatar.propTypes = { 83 | user: PropTypes.object, 84 | className: PropTypes.string 85 | }; 86 | 87 | export default UserAvatar; 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ____ __ ____ 3 | / __ \____ _____ ____/ /_ ____ / / /_ 4 | / /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/ 5 | / ____/ /_/ (__ |__ ) /_/ / /_/ / / /_ 6 | /_/ \__,_/____/____/_,___/\____/_/\__/ 7 | 8 | The open source password manager for teams 9 | Copyright (c) 2018 Passbolt SARL 10 | https://www.passbolt.com 11 | 12 | 13 | ## ARCHIVED 14 | 15 | This repository is archived and the code will not be updated. 16 | Use at your own risk. 17 | 18 | 19 | ## License 20 | 21 | This program is free software: you can redistribute it and/or modify 22 | it under the terms of the GNU Affero General Public License as 23 | published by the Free Software Foundation, either version 3 of the 24 | License, or (at your option) any later version. 25 | 26 | This program is distributed in the hope that it will be useful, 27 | but without any warranty; without even the implied warranty of 28 | merchantability or fitness for a particular purpose. See the 29 | GNU Affero General Public License for more details. 30 | 31 | [Affero General Public License v3](http://www.gnu.org/licenses/agpl-3.0.html) 32 | 33 | ## About Passbolt Appjs 34 | 35 | Passbolt Application Js is the browser application provided by the [passbolt_api](https://github.com/passbolt/passbolt_api) 36 | 37 | Find out more: [https://www.passbolt.com](https://www.passbolt.com "Passbolt Homepage") 38 | 39 | ### Trying out passbolt 40 | 41 | You can try a demo of passbolt at https://demo.passbolt.com. 42 | 43 | You will need to install a plugin, you can find some help here: 44 | https://www.passbolt.com/help/start/firefox 45 | 46 | ## Installing passbolt 47 | 48 | You can install passbolt on your own machine. Follow the instructions on the website here: 49 | https://www.passbolt.com/help/tech/install 50 | 51 | ## Contributing to passbolt 52 | 53 | Please check out CONTRIBUTING.md for more information on how to get involved! 54 | 55 | ## Reporting a security issue 56 | 57 | If you've found a security-related issue in passbolt, please don't open an issue on GitHub. 58 | Instead contact us at security@passbolt.com. In the spirit of responsible disclosure we ask that the reporter keep the issue confidential until we announce it. 59 | 60 | The passbolt team will take the following actions: 61 | - Try first to reproduce the issue and confirm the vulnerability. 62 | - Acknowledge to the reporter that we have received the issue and are working on a fix. 63 | - Get a fix/patch prepared and create associated automated tests. 64 | - Prepare a post describing the vulnerability and the possible exploits. 65 | - Release new versions of all affected major versions. 66 | - Prominently feature the problem in the release announcement. 67 | - Give credit in the release announcement to the reporter if they so desire. 68 | 69 | ## Credits 70 | 71 | https://www.passbolt.com/credits 72 | -------------------------------------------------------------------------------- /app/view/template/form/administration/email_notification/settings.stache: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 | 5 | 6 | 7 | 8 |
    9 | {{#if(foldersPluginEnabled)}} 10 |
    11 | 12 | 13 | 14 | 15 | 16 |
    17 |
    18 |
    19 | {{/if}} 20 |
    21 | 22 | 23 |
    24 |
    25 |
    26 |
    27 | 28 | 29 | 30 | 31 | 32 |
    33 |
    34 | 35 | 36 | 37 | 38 | 39 |
    40 |
    41 |
    42 |

    Email content visibility

    43 |

    44 | In this section you can adjust the composition of the emails, e.g. which information will be included in the 45 | notification. 46 |

    47 |
    48 | 49 | 50 | 51 | 52 | 53 |
    54 |
    55 | 56 | 57 |
    58 |
    59 | -------------------------------------------------------------------------------- /app/model/map/profile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import DefineMap from 'passbolt-mad/model/map/map'; 15 | // eslint-disable-next-line no-unused-vars 16 | import I18n from 'passbolt-mad/util/lang/i18n'; 17 | import ImageStorage from './image_storage'; 18 | 19 | const Profile = DefineMap.extend('passbolt.model.Profile', { 20 | id: 'string', 21 | first_name: 'string', 22 | last_name: 'string', 23 | avatar: ImageStorage, 24 | 25 | /** 26 | * Return the user full name. 27 | * @return {string} 28 | */ 29 | fullName: function() { 30 | return Profile.fullName(this); 31 | }, 32 | 33 | /** 34 | * Get the avatar image path 35 | * @param {string} version (optional) The version to get 36 | * @return {string} The image path 37 | */ 38 | avatarPath: function(version) { 39 | return Profile.avatarPath(this, version); 40 | } 41 | }); 42 | DefineMap.setReference('Profile', Profile); 43 | 44 | /** 45 | * Get full name. 46 | * @param profile 47 | * @return {string} 48 | */ 49 | Profile.fullName = function(profile) { 50 | const fullName = `${profile.first_name} ${profile.last_name}`; 51 | return fullName; 52 | }; 53 | 54 | /** 55 | * Get avatar path. 56 | * @param profile 57 | * @param version 58 | * @return {*} 59 | */ 60 | Profile.avatarPath = function(profile, version) { 61 | if (typeof profile.avatar != 'undefined' && profile.avatar.url != undefined) { 62 | return profile.avatar.imagePath(version); 63 | } else { 64 | return 'img/avatar/user.png'; 65 | } 66 | }; 67 | 68 | /* 69 | * Default validation rules. 70 | * Keep these rules in sync with the passbolt API. 71 | * @see https://github.com/passbolt/passbolt_api/src/Model/Table/PRofilesTable.php 72 | */ 73 | Profile.validationRules = { 74 | first_name: [ 75 | {rule: 'required', message: __('A first name is required')}, 76 | {rule: 'notEmpty', message: __('A first name is required')}, 77 | {rule: 'utf8', message: __('First name should be a valid utf8 string.')}, 78 | {rule: ['lengthBetween', 0, 255], message: __('The first name length should be maximum 255 characters.')} 79 | ], 80 | last_name: [ 81 | {rule: 'required', message: __('A last name is required')}, 82 | {rule: 'notEmpty', message: __('A last name is required')}, 83 | {rule: 'utf8', message: __('Last name should be a valid utf8 string.')}, 84 | {rule: ['lengthBetween', 0, 255], message: __('The last name length should be maximum 255 characters.')} 85 | ] 86 | }; 87 | 88 | export default Profile; 89 | -------------------------------------------------------------------------------- /app/model/map/tag.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Ajax from '../../net/ajax'; 15 | import connect from 'can-connect'; 16 | import connectDataUrl from 'can-connect/data/url/url'; 17 | import connectParse from 'can-connect/data/parse/parse'; 18 | import connectConstructor from 'can-connect/constructor/constructor'; 19 | import connectMap from 'can-connect/can/map/map'; 20 | import DefineList from 'passbolt-mad/model/list/list'; 21 | import DefineMap from 'passbolt-mad/model/map/map'; 22 | 23 | const Tag = DefineMap.extend('passbolt.model.Tag', { 24 | id: 'string', 25 | slug: 'string', 26 | user_id: 'string', 27 | is_shared: 'boolean' 28 | }); 29 | DefineMap.setReference('Tag', Tag); 30 | Tag.List = DefineList.extend({'#': {Type: Tag}}); 31 | 32 | /* 33 | * Default validation rules. 34 | * Keep these rules in sync with the passbolt API. 35 | */ 36 | Tag.validationRules = { 37 | id: [ 38 | {rule: 'uuid'} 39 | ], 40 | slug: [ 41 | {rule: 'required', message: __('Tag can not be empty')}, 42 | {rule: ['maxLength', 128], message: __('Tag can not be more than %s characters in length', 128)}, 43 | {rule: 'utf8Extended', message: __('Tag should be a valid utf8 string.')} 44 | ] 45 | }; 46 | 47 | /** 48 | * Update the resource tags 49 | * @param {string} resourceId The target resource to update the tags for 50 | * @param {array} slugs The list tags 51 | */ 52 | Tag.updateResourceTags = function(resourceId, slugs) { 53 | return Ajax.request({ 54 | url: 'tags/{resourceId}.json?api-version=v2', 55 | type: 'POST', 56 | params: {Tags: slugs, resourceId: resourceId} 57 | }).then(data => Promise.resolve(new Tag.List(data))); 58 | }; 59 | 60 | Tag.connection = connect([connectParse, connectDataUrl, connectConstructor, connectMap], { 61 | Map: Tag, 62 | List: Tag.List, 63 | url: { 64 | resource: '/', 65 | getListData: function(params) { 66 | params = params || {}; 67 | params['api-version'] = 'v2'; 68 | return Ajax.request({ 69 | url: 'tags.json', 70 | type: 'GET', 71 | params: params 72 | }); 73 | }, 74 | destroyData: function(params) { 75 | return Ajax.request({ 76 | url: `tags/${params.id}.json?api-version=v2`, 77 | type: 'DELETE' 78 | }); 79 | }, 80 | updateData: function(params) { 81 | return Ajax.request({ 82 | url: `tags/${params.id}.json?api-version=v2`, 83 | type: 'PUT', 84 | params: params 85 | }); 86 | } 87 | } 88 | }); 89 | 90 | export default Tag; 91 | -------------------------------------------------------------------------------- /app/model/map/comment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Ajax from '../../net/ajax'; 15 | import connect from 'can-connect'; 16 | import connectDataUrl from 'can-connect/data/url/url'; 17 | import connectParse from 'can-connect/data/parse/parse'; 18 | import connectConstructor from 'can-connect/constructor/constructor'; 19 | import connectMap from 'can-connect/can/map/map'; 20 | import DefineList from 'passbolt-mad/model/list/list'; 21 | import DefineMap from 'passbolt-mad/model/map/map'; 22 | // eslint-disable-next-line no-unused-vars 23 | import I18n from 'passbolt-mad/util/lang/i18n'; 24 | import User from './user'; 25 | 26 | const Comment = DefineMap.extend('passbolt.model.Comment', { 27 | id: 'string', 28 | parent_id: 'string', 29 | foreign_model: 'string', 30 | foreign_key: 'string', 31 | content: 'string', 32 | created: 'string', 33 | modified: 'string', 34 | creator: User, 35 | modifier: User 36 | }); 37 | DefineMap.setReference('Comment', Comment); 38 | Comment.List = DefineList.extend({'#': {Type: Comment}}); 39 | 40 | /* 41 | * Default validation rules. 42 | * Keep these rules in sync with the passbolt API. 43 | * @see https://github.com/passbolt/passbolt_api/src/Model/Table/CommentsTable.php 44 | */ 45 | Comment.validationRules = { 46 | id: [ 47 | {rule: 'uuid'} 48 | ], 49 | content: [ 50 | {rule: 'required', message: __('A comment is required.')}, 51 | {rule: ['lengthBetween', 1, 255], message: __('The comment should be between %s and %s characters.', 1, 255)}, 52 | {rule: 'utf8Extended', message: __('The comment should be a valid utf8 string.')} 53 | ] 54 | }; 55 | 56 | Comment.connection = connect([connectParse, connectDataUrl, connectConstructor, connectMap], { 57 | Map: Comment, 58 | List: Comment.List, 59 | url: { 60 | resource: '/', 61 | createData: function(params) { 62 | return Ajax.request({ 63 | url: 'comments/resource/{foreign_key}.json?api-version=v2', 64 | type: 'POST', 65 | params: params 66 | }); 67 | }, 68 | getListData: function(params) { 69 | params = params || {}; 70 | params['api-version'] = 'v2'; 71 | return Ajax.request({ 72 | url: 'comments/resource/{foreignKey}.json', 73 | type: 'GET', 74 | params: params 75 | }); 76 | }, 77 | destroyData: function(params) { 78 | return Ajax.request({ 79 | url: `comments/${params.id}.json?api-version=v2`, 80 | type: 'DELETE' 81 | }); 82 | } 83 | } 84 | }); 85 | 86 | export default Comment; 87 | -------------------------------------------------------------------------------- /app/form/comment/create.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import FeedbackComponent from 'passbolt-mad/form/feedback'; 15 | import Form from 'passbolt-mad/form/form'; 16 | import TextboxComponent from 'passbolt-mad/form/element/textbox'; 17 | import User from '../../model/map/user'; 18 | 19 | import template from '../../view/template/form/comment/add.stache'; 20 | 21 | const CreateForm = Form.extend('passbolt.form.comment.Create', /** @static */ { 22 | 23 | defaults: { 24 | foreignModel: null, 25 | foreignKey: null, 26 | template: template, 27 | commentContentField: null 28 | } 29 | }, /** @prototype */ { 30 | 31 | /** 32 | * @inheritdoc 33 | */ 34 | init: function(el, options) { 35 | this._super(el, options); 36 | this.setViewData('user', User.getCurrent()); 37 | }, 38 | 39 | /** 40 | * @inheritdoc 41 | */ 42 | afterStart: function() { 43 | // parent_id hidden field 44 | this.addElement( 45 | new TextboxComponent(`#${this.element.id} .js_comment_parent_id`, { 46 | modelReference: 'Comment.parent_id' 47 | }).start() 48 | ); 49 | 50 | // foreign_key hidden field 51 | this.addElement( 52 | new TextboxComponent(`#${this.element.id} .js_comment_foreign_key`, { 53 | modelReference: 'Comment.foreign_key' 54 | }).start().setValue(this.options.foreignKey) 55 | ); 56 | 57 | // feedback. 58 | this.options.commentContentField = new TextboxComponent(`#${this.element.id} .js_comment_content`, { 59 | modelReference: 'Comment.content' 60 | }).start(); 61 | this.addElement( 62 | this.options.commentContentField, 63 | new FeedbackComponent(`#${this.element.id} .js_comment_content_feedback`, {}).start() 64 | ); 65 | }, 66 | 67 | /** 68 | * Empty content of the comment content field. 69 | */ 70 | emptyContent: function() { 71 | this.options.commentContentField.setValue(''); 72 | }, 73 | 74 | /* ************************************************************** */ 75 | /* LISTEN TO THE VIEW EVENTS */ 76 | /* ************************************************************** */ 77 | 78 | /** 79 | * State ready. 80 | * Empty the comment content field. 81 | */ 82 | stateReady: function() { 83 | this.options.commentContentField.setValue(''); 84 | }, 85 | 86 | /** 87 | * State hidden. 88 | * @param go 89 | */ 90 | stateHidden: function(go) { 91 | this._super(go); 92 | /* 93 | * Reinitialize number of validations to avoid inline validation 94 | * each time the form appears. 95 | */ 96 | this.validations = 0; 97 | } 98 | }); 99 | 100 | export default CreateForm; 101 | -------------------------------------------------------------------------------- /app/view/template/form/administration/mfa/settings.stache: -------------------------------------------------------------------------------- 1 |
    2 |

    3 |

    4 | {{__('The Time-based One Time Password provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication.')}} 5 |

    6 |

    7 | {{__('The Time-based One Time Password provider is disabled for all users.')}} 8 |

    9 |
    10 | 11 |
    12 |

    13 |

    14 | {{__('The Yubikey provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication.')}} 15 |

    16 |

    17 | {{__('The Yubikey provider is disabled for all users.')}} 18 |

    19 |
    20 |
    21 | 22 | 23 |
    24 |
    25 |
    26 | 27 | 28 |
    29 |
    30 |
    31 |
    32 | 33 |
    34 |

    35 |

    36 | {{__('The Duo provider is enabled for all users. They can setup this provider in their profile and use it as second factor authentication.')}} 37 |

    38 |

    39 | {{__('The Duo provider is disabled for all users.')}} 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 | -------------------------------------------------------------------------------- /app/component/password/primary_sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SARL (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.0.0 13 | */ 14 | import Config from 'passbolt-mad/config/config'; 15 | import FoldersFilterSidebarSectionComponent from '../password/folders_filter_sidebar_section'; 16 | import GroupsFilterSidebarSectionComponent from '../password/groups_filter_sidebar_section'; 17 | import PrimarySidebarAbstractComponent from '../workspace/primary_sidebar'; 18 | import ShortcutsFilterSidebarSectionComponent from '../password/shortcuts_filter_sidebar_section'; 19 | import TagsFilterSidebarSectionComponent from '../tag/tags_filter_sidebar_section'; 20 | 21 | import template from '../../view/template/component/password/primary_sidebar.stache'; 22 | 23 | const PrimarySidebarComponent = PrimarySidebarAbstractComponent.extend('passbolt.component.password.PrimarySidebar', /** @static */ { 24 | 25 | defaults: { 26 | label: 'Password Workspace Primary Sidebar', 27 | template: template, 28 | defaultFilter: null, 29 | selectedGroups: null, 30 | selectedTags: null 31 | } 32 | 33 | }, /** @prototype */ { 34 | 35 | /** 36 | * @inheritdoc 37 | */ 38 | afterStart: function() { 39 | this._initShortcutsFilterSection(); 40 | this._initFoldersFilterSection(); 41 | this._initGroupsFilterSection(); 42 | this._initTagsFilterSection(); 43 | this._super(); 44 | }, 45 | 46 | /** 47 | * Initialize the shortcuts filter section 48 | */ 49 | _initShortcutsFilterSection: function() { 50 | const component = new ShortcutsFilterSidebarSectionComponent('#js_wsp_pwd_filter_shortcuts', { 51 | allFilter: this.options.defaultFilter 52 | }); 53 | component.start(); 54 | }, 55 | 56 | /** 57 | * Initialize the groups filter section 58 | */ 59 | _initFoldersFilterSection: function() { 60 | const pluginFoldersEnabled = Config.read('server.passbolt.plugins.folders'); 61 | if (!pluginFoldersEnabled) { 62 | return; 63 | } 64 | const component = new FoldersFilterSidebarSectionComponent('#js_wsp_pwd_filter_folders_section', { 65 | selectedGroups: this.options.selectedFolders 66 | }); 67 | component.start(); 68 | }, 69 | 70 | /** 71 | * Initialize the groups filter section 72 | */ 73 | _initGroupsFilterSection: function() { 74 | const component = new GroupsFilterSidebarSectionComponent('#js_wsp_pwd_password_categories', { 75 | selectedGroups: this.options.selectedGroups 76 | }); 77 | component.start(); 78 | }, 79 | 80 | /** 81 | * Initialize the tags filter section 82 | */ 83 | _initTagsFilterSection: function() { 84 | const plugins = Config.read('server.passbolt.plugins'); 85 | if (plugins && plugins.tags) { 86 | const component = new TagsFilterSidebarSectionComponent('#js_wsp_pwd_filter_tags_section', { 87 | selectedTags: this.options.selectedTags 88 | }); 89 | component.start(); 90 | } 91 | } 92 | 93 | }); 94 | 95 | export default PrimarySidebarComponent; 96 | -------------------------------------------------------------------------------- /app/model/map/email_notification_settings.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Passbolt ~ Open source password manager for teams 3 | * Copyright (c) Passbolt SARL (https://www.passbolt.com) 4 | * 5 | * Licensed under GNU Affero General Public License version 3 of the or any later version. 6 | * For full copyright and license information, please see the LICENSE.txt 7 | * Redistributions of files must retain the above copyright notice. 8 | * 9 | * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com) 10 | * @license https://opensource.org/licenses/AGPL-3.0 AGPL License 11 | * @link https://www.passbolt.com Passbolt(tm) 12 | * @since 2.10.0 13 | */ 14 | import Ajax from '../../net/ajax'; 15 | import connect from 'can-connect'; 16 | import connectDataUrl from 'can-connect/data/url/url'; 17 | import connectParse from 'can-connect/data/parse/parse'; 18 | import connectConstructor from 'can-connect/constructor/constructor'; 19 | import connectMap from 'can-connect/can/map/map'; 20 | import DefineMap from 'passbolt-mad/model/map/map'; 21 | // eslint-disable-next-line no-unused-vars 22 | import I18n from 'passbolt-mad/util/lang/i18n'; 23 | import 'urijs/src/punycode'; 24 | import 'urijs/src/SecondLevelDomains'; 25 | import 'urijs/src/IPv6'; 26 | import uuid from 'uuid/v4'; 27 | 28 | const EmailNotificationSettings = DefineMap.extend('passbolt.model.EmailNotificationSettings', { 29 | id: { 30 | type: 'string', 31 | value: () => uuid() 32 | }, 33 | 'show_comment': 'boolean', 34 | 'show_description': 'boolean', 35 | 'show_secret': 'boolean', 36 | 'show_uri': 'boolean', 37 | 'show_username': 'boolean', 38 | 'send_comment_add': 'boolean', 39 | 'send_password_create': 'boolean', 40 | 'send_password_share': 'boolean', 41 | 'send_password_update': 'boolean', 42 | 'send_password_delete': 'boolean', 43 | 'send_user_create': 'boolean', 44 | 'send_user_recover': 'boolean', 45 | 'send_group_delete': 'boolean', 46 | 'send_group_user_add': 'boolean', 47 | 'send_group_user_delete': 'boolean', 48 | 'send_group_user_update': 'boolean', 49 | 'send_group_manager_update': 'boolean', 50 | 'send_folder_deleted': 'boolean', 51 | 'send_folder_created': 'boolean', 52 | 'send_folder_updated': 'boolean', 53 | 'send_folder_share_created': 'boolean', 54 | 'send_folder_share_dropped': 'boolean', 55 | }); 56 | DefineMap.setReference('EmailNotificationSettings', EmailNotificationSettings); 57 | 58 | /** 59 | * Check if the settings are overridden by file 60 | * @param {object} data 61 | * @returns boolean 62 | */ 63 | EmailNotificationSettings.settingsOverridenByfile = function(data) { 64 | return data.sources_file === true && data.sources_database === true; 65 | }; 66 | 67 | EmailNotificationSettings.fileConfigExists = function(data) { 68 | return data.sources_file === true; 69 | }; 70 | 71 | EmailNotificationSettings.connection = connect([connectParse, connectDataUrl, connectConstructor, connectMap], { 72 | Map: EmailNotificationSettings, 73 | url: { 74 | resource: '/', 75 | getData: function() { 76 | const params = {}; 77 | params['api-version'] = 'v2'; 78 | return Ajax.request({ 79 | url: 'settings/emails/notifications.json', 80 | type: 'GET', 81 | params: params 82 | }); 83 | }, 84 | updateData: function(params) { 85 | return Ajax.request({ 86 | url: 'settings/emails/notifications.json?api-version=v2', 87 | type: 'POST', 88 | params: params 89 | }); 90 | } 91 | } 92 | }); 93 | 94 | export default EmailNotificationSettings; 95 | --------------------------------------------------------------------------------