feat: introduce personal access tokens for authorization (#4094)
Co-authored-by: Nivedin <53208152+nivedin@users.noreply.github.com>
This commit is contained in:
@@ -208,7 +208,8 @@
|
|||||||
"remove_telemetry": "Are you sure you want to opt-out of Telemetry?",
|
"remove_telemetry": "Are you sure you want to opt-out of Telemetry?",
|
||||||
"request_change": "Are you sure you want to discard current request, unsaved changes will be lost.",
|
"request_change": "Are you sure you want to discard current request, unsaved changes will be lost.",
|
||||||
"save_unsaved_tab": "Do you want to save changes made in this tab?",
|
"save_unsaved_tab": "Do you want to save changes made in this tab?",
|
||||||
"sync": "Would you like to restore your workspace from cloud? This will discard your local progress."
|
"sync": "Would you like to restore your workspace from cloud? This will discard your local progress.",
|
||||||
|
"delete_access_token": "Are you sure you want to delete the access token {tokenLabel}?"
|
||||||
},
|
},
|
||||||
"context_menu": {
|
"context_menu": {
|
||||||
"add_parameters": "Add to parameters",
|
"add_parameters": "Add to parameters",
|
||||||
@@ -270,7 +271,8 @@
|
|||||||
"subscription": "Subscriptions are empty",
|
"subscription": "Subscriptions are empty",
|
||||||
"team_name": "Workspace name empty",
|
"team_name": "Workspace name empty",
|
||||||
"teams": "You don't belong to any workspaces",
|
"teams": "You don't belong to any workspaces",
|
||||||
"tests": "There are no tests for this request"
|
"tests": "There are no tests for this request",
|
||||||
|
"access_tokens": "Access tokens are empty"
|
||||||
},
|
},
|
||||||
"environment": {
|
"environment": {
|
||||||
"add_to_global": "Add to Global",
|
"add_to_global": "Add to Global",
|
||||||
@@ -342,7 +344,10 @@
|
|||||||
"script_fail": "Could not execute pre-request script",
|
"script_fail": "Could not execute pre-request script",
|
||||||
"something_went_wrong": "Something went wrong",
|
"something_went_wrong": "Something went wrong",
|
||||||
"test_script_fail": "Could not execute post-request script",
|
"test_script_fail": "Could not execute post-request script",
|
||||||
"reading_files": "Error while reading one or more files."
|
"reading_files": "Error while reading one or more files.",
|
||||||
|
"fetching_access_tokens_list": "Something went wrong while fetching the list of tokens",
|
||||||
|
"generate_access_token": "Something went wrong while generating the access token",
|
||||||
|
"delete_access_token": "Something went wrong while deleting the access token"
|
||||||
},
|
},
|
||||||
"export": {
|
"export": {
|
||||||
"as_json": "Export as JSON",
|
"as_json": "Export as JSON",
|
||||||
@@ -1033,5 +1038,27 @@
|
|||||||
"login_to_continue": "Login to continue",
|
"login_to_continue": "Login to continue",
|
||||||
"login_to_continue_description": "You need to be logged in to access this Hoppscotch Enterprise Instance.",
|
"login_to_continue_description": "You need to be logged in to access this Hoppscotch Enterprise Instance.",
|
||||||
"error_fetching_site_protection_status": "Something Went Wrong While Fetching Site Protection Status"
|
"error_fetching_site_protection_status": "Something Went Wrong While Fetching Site Protection Status"
|
||||||
|
},
|
||||||
|
"access_tokens": {
|
||||||
|
"tab_title": "Tokens",
|
||||||
|
"section_title": "Personal Access Tokens",
|
||||||
|
"section_description": "Personal access tokens currently helps you connect the CLI to your Hoppscotch account",
|
||||||
|
"last_used_on": "Last used on",
|
||||||
|
"expires_on": "Expires on",
|
||||||
|
"no_expiration": "No expiration",
|
||||||
|
"expired": "Expired",
|
||||||
|
"copy_token_warning": "Make sure to copy your personal access token now. You won't be able to see it again!",
|
||||||
|
"token_purpose": "What's this token for?",
|
||||||
|
"expiration_label": "Expiration",
|
||||||
|
"scope_label": "Scope",
|
||||||
|
"workspace_read_only_access": "Read-only access to workspace data.",
|
||||||
|
"personal_workspace_access_limitation": "Personal Access Tokens can't access your personal workspace.",
|
||||||
|
"generate_token": "Generate Token",
|
||||||
|
"invalid_label": "Please provide a label for the token",
|
||||||
|
"no_expiration_verbose": "This token will never expire!",
|
||||||
|
"token_expires_on": "This token will expire on",
|
||||||
|
"generate_new_token": "Generate new token",
|
||||||
|
"generate_modal_title": "New Personal Access Token",
|
||||||
|
"deletion_success": "The access token {label} has been deleted"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
421
packages/hoppscotch-common/src/components.d.ts
vendored
421
packages/hoppscotch-common/src/components.d.ts
vendored
@@ -1,216 +1,223 @@
|
|||||||
// generated by unplugin-vue-components
|
// generated by unplugin-vue-components
|
||||||
// We suggest you to commit this file into source control
|
// We suggest you to commit this file into source control
|
||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
import '@vue/runtime-core'
|
import "@vue/runtime-core"
|
||||||
|
|
||||||
export {}
|
export {}
|
||||||
|
|
||||||
declare module '@vue/runtime-core' {
|
declare module "@vue/runtime-core" {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
AppActionHandler: typeof import('./components/app/ActionHandler.vue')['default']
|
AccessTokens: (typeof import("./components/accessTokens/index.vue"))["default"]
|
||||||
AppBanner: typeof import('./components/app/Banner.vue')['default']
|
AccessTokensGenerate: (typeof import("./components/accessTokens/Generate.vue"))["default"]
|
||||||
AppContextMenu: typeof import('./components/app/ContextMenu.vue')['default']
|
AccessTokensGenerateModal: (typeof import("./components/accessTokens/GenerateModal.vue"))["default"]
|
||||||
AppDeveloperOptions: typeof import('./components/app/DeveloperOptions.vue')['default']
|
AccessTokensList: (typeof import("./components/accessTokens/List.vue"))["default"]
|
||||||
AppFooter: typeof import('./components/app/Footer.vue')['default']
|
AccessTokensOverview: (typeof import("./components/accessTokens/Overview.vue"))["default"]
|
||||||
AppGitHubStarButton: typeof import('./components/app/GitHubStarButton.vue')['default']
|
AppActionHandler: (typeof import("./components/app/ActionHandler.vue"))["default"]
|
||||||
AppHeader: typeof import('./components/app/Header.vue')['default']
|
AppBanner: (typeof import("./components/app/Banner.vue"))["default"]
|
||||||
AppInspection: typeof import('./components/app/Inspection.vue')['default']
|
AppContextMenu: (typeof import("./components/app/ContextMenu.vue"))["default"]
|
||||||
AppInterceptor: typeof import('./components/app/Interceptor.vue')['default']
|
AppDeveloperOptions: (typeof import("./components/app/DeveloperOptions.vue"))["default"]
|
||||||
AppLogo: typeof import('./components/app/Logo.vue')['default']
|
AppFooter: (typeof import("./components/app/Footer.vue"))["default"]
|
||||||
AppOptions: typeof import('./components/app/Options.vue')['default']
|
AppGitHubStarButton: (typeof import("./components/app/GitHubStarButton.vue"))["default"]
|
||||||
AppPaneLayout: typeof import('./components/app/PaneLayout.vue')['default']
|
AppHeader: (typeof import("./components/app/Header.vue"))["default"]
|
||||||
AppShare: typeof import('./components/app/Share.vue')['default']
|
AppInspection: (typeof import("./components/app/Inspection.vue"))["default"]
|
||||||
AppShortcuts: typeof import('./components/app/Shortcuts.vue')['default']
|
AppInterceptor: (typeof import("./components/app/Interceptor.vue"))["default"]
|
||||||
AppShortcutsEntry: typeof import('./components/app/ShortcutsEntry.vue')['default']
|
AppLogo: (typeof import("./components/app/Logo.vue"))["default"]
|
||||||
AppShortcutsPrompt: typeof import('./components/app/ShortcutsPrompt.vue')['default']
|
AppOptions: (typeof import("./components/app/Options.vue"))["default"]
|
||||||
AppSidenav: typeof import('./components/app/Sidenav.vue')['default']
|
AppPaneLayout: (typeof import("./components/app/PaneLayout.vue"))["default"]
|
||||||
AppSpotlight: typeof import('./components/app/spotlight/index.vue')['default']
|
AppShare: (typeof import("./components/app/Share.vue"))["default"]
|
||||||
AppSpotlightEntry: typeof import('./components/app/spotlight/Entry.vue')['default']
|
AppShortcuts: (typeof import("./components/app/Shortcuts.vue"))["default"]
|
||||||
AppSpotlightEntryGQLHistory: typeof import('./components/app/spotlight/entry/GQLHistory.vue')['default']
|
AppShortcutsEntry: (typeof import("./components/app/ShortcutsEntry.vue"))["default"]
|
||||||
AppSpotlightEntryGQLRequest: typeof import('./components/app/spotlight/entry/GQLRequest.vue')['default']
|
AppShortcutsPrompt: (typeof import("./components/app/ShortcutsPrompt.vue"))["default"]
|
||||||
AppSpotlightEntryIconSelected: typeof import('./components/app/spotlight/entry/IconSelected.vue')['default']
|
AppSidenav: (typeof import("./components/app/Sidenav.vue"))["default"]
|
||||||
AppSpotlightEntryRESTHistory: typeof import('./components/app/spotlight/entry/RESTHistory.vue')['default']
|
AppSpotlight: (typeof import("./components/app/spotlight/index.vue"))["default"]
|
||||||
AppSpotlightEntryRESTRequest: typeof import('./components/app/spotlight/entry/RESTRequest.vue')['default']
|
AppSpotlightEntry: (typeof import("./components/app/spotlight/Entry.vue"))["default"]
|
||||||
AppSpotlightEntryRESTTeamRequestEntry: typeof import('./components/app/spotlight/entry/RESTTeamRequestEntry.vue')['default']
|
AppSpotlightEntryGQLHistory: (typeof import("./components/app/spotlight/entry/GQLHistory.vue"))["default"]
|
||||||
AppSpotlightSearch: typeof import('./components/app/SpotlightSearch.vue')['default']
|
AppSpotlightEntryGQLRequest: (typeof import("./components/app/spotlight/entry/GQLRequest.vue"))["default"]
|
||||||
AppSupport: typeof import('./components/app/Support.vue')['default']
|
AppSpotlightEntryIconSelected: (typeof import("./components/app/spotlight/entry/IconSelected.vue"))["default"]
|
||||||
Collections: typeof import('./components/collections/index.vue')['default']
|
AppSpotlightEntryRESTHistory: (typeof import("./components/app/spotlight/entry/RESTHistory.vue"))["default"]
|
||||||
CollectionsAdd: typeof import('./components/collections/Add.vue')['default']
|
AppSpotlightEntryRESTRequest: (typeof import("./components/app/spotlight/entry/RESTRequest.vue"))["default"]
|
||||||
CollectionsAddFolder: typeof import('./components/collections/AddFolder.vue')['default']
|
AppSpotlightEntryRESTTeamRequestEntry: (typeof import("./components/app/spotlight/entry/RESTTeamRequestEntry.vue"))["default"]
|
||||||
CollectionsAddRequest: typeof import('./components/collections/AddRequest.vue')['default']
|
AppSpotlightSearch: (typeof import("./components/app/SpotlightSearch.vue"))["default"]
|
||||||
CollectionsCollection: typeof import('./components/collections/Collection.vue')['default']
|
AppSupport: (typeof import("./components/app/Support.vue"))["default"]
|
||||||
CollectionsEdit: typeof import('./components/collections/Edit.vue')['default']
|
Collections: (typeof import("./components/collections/index.vue"))["default"]
|
||||||
CollectionsEditFolder: typeof import('./components/collections/EditFolder.vue')['default']
|
CollectionsAdd: (typeof import("./components/collections/Add.vue"))["default"]
|
||||||
CollectionsEditRequest: typeof import('./components/collections/EditRequest.vue')['default']
|
CollectionsAddFolder: (typeof import("./components/collections/AddFolder.vue"))["default"]
|
||||||
CollectionsGraphql: typeof import('./components/collections/graphql/index.vue')['default']
|
CollectionsAddRequest: (typeof import("./components/collections/AddRequest.vue"))["default"]
|
||||||
CollectionsGraphqlAdd: typeof import('./components/collections/graphql/Add.vue')['default']
|
CollectionsCollection: (typeof import("./components/collections/Collection.vue"))["default"]
|
||||||
CollectionsGraphqlAddFolder: typeof import('./components/collections/graphql/AddFolder.vue')['default']
|
CollectionsEdit: (typeof import("./components/collections/Edit.vue"))["default"]
|
||||||
CollectionsGraphqlAddRequest: typeof import('./components/collections/graphql/AddRequest.vue')['default']
|
CollectionsEditFolder: (typeof import("./components/collections/EditFolder.vue"))["default"]
|
||||||
CollectionsGraphqlCollection: typeof import('./components/collections/graphql/Collection.vue')['default']
|
CollectionsEditRequest: (typeof import("./components/collections/EditRequest.vue"))["default"]
|
||||||
CollectionsGraphqlEdit: typeof import('./components/collections/graphql/Edit.vue')['default']
|
CollectionsGraphql: (typeof import("./components/collections/graphql/index.vue"))["default"]
|
||||||
CollectionsGraphqlEditFolder: typeof import('./components/collections/graphql/EditFolder.vue')['default']
|
CollectionsGraphqlAdd: (typeof import("./components/collections/graphql/Add.vue"))["default"]
|
||||||
CollectionsGraphqlEditRequest: typeof import('./components/collections/graphql/EditRequest.vue')['default']
|
CollectionsGraphqlAddFolder: (typeof import("./components/collections/graphql/AddFolder.vue"))["default"]
|
||||||
CollectionsGraphqlFolder: typeof import('./components/collections/graphql/Folder.vue')['default']
|
CollectionsGraphqlAddRequest: (typeof import("./components/collections/graphql/AddRequest.vue"))["default"]
|
||||||
CollectionsGraphqlImportExport: typeof import('./components/collections/graphql/ImportExport.vue')['default']
|
CollectionsGraphqlCollection: (typeof import("./components/collections/graphql/Collection.vue"))["default"]
|
||||||
CollectionsGraphqlRequest: typeof import('./components/collections/graphql/Request.vue')['default']
|
CollectionsGraphqlEdit: (typeof import("./components/collections/graphql/Edit.vue"))["default"]
|
||||||
CollectionsImportExport: typeof import('./components/collections/ImportExport.vue')['default']
|
CollectionsGraphqlEditFolder: (typeof import("./components/collections/graphql/EditFolder.vue"))["default"]
|
||||||
CollectionsMyCollections: typeof import('./components/collections/MyCollections.vue')['default']
|
CollectionsGraphqlEditRequest: (typeof import("./components/collections/graphql/EditRequest.vue"))["default"]
|
||||||
CollectionsProperties: typeof import('./components/collections/Properties.vue')['default']
|
CollectionsGraphqlFolder: (typeof import("./components/collections/graphql/Folder.vue"))["default"]
|
||||||
CollectionsRequest: typeof import('./components/collections/Request.vue')['default']
|
CollectionsGraphqlImportExport: (typeof import("./components/collections/graphql/ImportExport.vue"))["default"]
|
||||||
CollectionsSaveRequest: typeof import('./components/collections/SaveRequest.vue')['default']
|
CollectionsGraphqlRequest: (typeof import("./components/collections/graphql/Request.vue"))["default"]
|
||||||
CollectionsTeamCollections: typeof import('./components/collections/TeamCollections.vue')['default']
|
CollectionsImportExport: (typeof import("./components/collections/ImportExport.vue"))["default"]
|
||||||
CookiesAllModal: typeof import('./components/cookies/AllModal.vue')['default']
|
CollectionsMyCollections: (typeof import("./components/collections/MyCollections.vue"))["default"]
|
||||||
CookiesEditCookie: typeof import('./components/cookies/EditCookie.vue')['default']
|
CollectionsProperties: (typeof import("./components/collections/Properties.vue"))["default"]
|
||||||
Embeds: typeof import('./components/embeds/index.vue')['default']
|
CollectionsRequest: (typeof import("./components/collections/Request.vue"))["default"]
|
||||||
Environments: typeof import('./components/environments/index.vue')['default']
|
CollectionsSaveRequest: (typeof import("./components/collections/SaveRequest.vue"))["default"]
|
||||||
EnvironmentsAdd: typeof import('./components/environments/Add.vue')['default']
|
CollectionsTeamCollections: (typeof import("./components/collections/TeamCollections.vue"))["default"]
|
||||||
EnvironmentsImportExport: typeof import('./components/environments/ImportExport.vue')['default']
|
CookiesAllModal: (typeof import("./components/cookies/AllModal.vue"))["default"]
|
||||||
EnvironmentsMy: typeof import('./components/environments/my/index.vue')['default']
|
CookiesEditCookie: (typeof import("./components/cookies/EditCookie.vue"))["default"]
|
||||||
EnvironmentsMyDetails: typeof import('./components/environments/my/Details.vue')['default']
|
Embeds: (typeof import("./components/embeds/index.vue"))["default"]
|
||||||
EnvironmentsMyEnvironment: typeof import('./components/environments/my/Environment.vue')['default']
|
Environments: (typeof import("./components/environments/index.vue"))["default"]
|
||||||
EnvironmentsSelector: typeof import('./components/environments/Selector.vue')['default']
|
EnvironmentsAdd: (typeof import("./components/environments/Add.vue"))["default"]
|
||||||
EnvironmentsTeams: typeof import('./components/environments/teams/index.vue')['default']
|
EnvironmentsImportExport: (typeof import("./components/environments/ImportExport.vue"))["default"]
|
||||||
EnvironmentsTeamsDetails: typeof import('./components/environments/teams/Details.vue')['default']
|
EnvironmentsMy: (typeof import("./components/environments/my/index.vue"))["default"]
|
||||||
EnvironmentsTeamsEnvironment: typeof import('./components/environments/teams/Environment.vue')['default']
|
EnvironmentsMyDetails: (typeof import("./components/environments/my/Details.vue"))["default"]
|
||||||
FirebaseLogin: typeof import('./components/firebase/Login.vue')['default']
|
EnvironmentsMyEnvironment: (typeof import("./components/environments/my/Environment.vue"))["default"]
|
||||||
FirebaseLogout: typeof import('./components/firebase/Logout.vue')['default']
|
EnvironmentsSelector: (typeof import("./components/environments/Selector.vue"))["default"]
|
||||||
GraphqlAuthorization: typeof import('./components/graphql/Authorization.vue')['default']
|
EnvironmentsTeams: (typeof import("./components/environments/teams/index.vue"))["default"]
|
||||||
GraphqlField: typeof import('./components/graphql/Field.vue')['default']
|
EnvironmentsTeamsDetails: (typeof import("./components/environments/teams/Details.vue"))["default"]
|
||||||
GraphqlHeaders: typeof import('./components/graphql/Headers.vue')['default']
|
EnvironmentsTeamsEnvironment: (typeof import("./components/environments/teams/Environment.vue"))["default"]
|
||||||
GraphqlQuery: typeof import('./components/graphql/Query.vue')['default']
|
FirebaseLogin: (typeof import("./components/firebase/Login.vue"))["default"]
|
||||||
GraphqlRequest: typeof import('./components/graphql/Request.vue')['default']
|
FirebaseLogout: (typeof import("./components/firebase/Logout.vue"))["default"]
|
||||||
GraphqlRequestOptions: typeof import('./components/graphql/RequestOptions.vue')['default']
|
GraphqlAuthorization: (typeof import("./components/graphql/Authorization.vue"))["default"]
|
||||||
GraphqlRequestTab: typeof import('./components/graphql/RequestTab.vue')['default']
|
GraphqlField: (typeof import("./components/graphql/Field.vue"))["default"]
|
||||||
GraphqlResponse: typeof import('./components/graphql/Response.vue')['default']
|
GraphqlHeaders: (typeof import("./components/graphql/Headers.vue"))["default"]
|
||||||
GraphqlSidebar: typeof import('./components/graphql/Sidebar.vue')['default']
|
GraphqlQuery: (typeof import("./components/graphql/Query.vue"))["default"]
|
||||||
GraphqlSubscriptionLog: typeof import('./components/graphql/SubscriptionLog.vue')['default']
|
GraphqlRequest: (typeof import("./components/graphql/Request.vue"))["default"]
|
||||||
GraphqlTabHead: typeof import('./components/graphql/TabHead.vue')['default']
|
GraphqlRequestOptions: (typeof import("./components/graphql/RequestOptions.vue"))["default"]
|
||||||
GraphqlType: typeof import('./components/graphql/Type.vue')['default']
|
GraphqlRequestTab: (typeof import("./components/graphql/RequestTab.vue"))["default"]
|
||||||
GraphqlTypeLink: typeof import('./components/graphql/TypeLink.vue')['default']
|
GraphqlResponse: (typeof import("./components/graphql/Response.vue"))["default"]
|
||||||
GraphqlVariable: typeof import('./components/graphql/Variable.vue')['default']
|
GraphqlSidebar: (typeof import("./components/graphql/Sidebar.vue"))["default"]
|
||||||
History: typeof import('./components/history/index.vue')['default']
|
GraphqlSubscriptionLog: (typeof import("./components/graphql/SubscriptionLog.vue"))["default"]
|
||||||
HistoryGraphqlCard: typeof import('./components/history/graphql/Card.vue')['default']
|
GraphqlTabHead: (typeof import("./components/graphql/TabHead.vue"))["default"]
|
||||||
HistoryRestCard: typeof import('./components/history/rest/Card.vue')['default']
|
GraphqlType: (typeof import("./components/graphql/Type.vue"))["default"]
|
||||||
HoppButtonPrimary: typeof import('@hoppscotch/ui')['HoppButtonPrimary']
|
GraphqlTypeLink: (typeof import("./components/graphql/TypeLink.vue"))["default"]
|
||||||
HoppButtonSecondary: typeof import('@hoppscotch/ui')['HoppButtonSecondary']
|
GraphqlVariable: (typeof import("./components/graphql/Variable.vue"))["default"]
|
||||||
HoppSmartAnchor: typeof import('@hoppscotch/ui')['HoppSmartAnchor']
|
History: (typeof import("./components/history/index.vue"))["default"]
|
||||||
HoppSmartCheckbox: typeof import('@hoppscotch/ui')['HoppSmartCheckbox']
|
HistoryGraphqlCard: (typeof import("./components/history/graphql/Card.vue"))["default"]
|
||||||
HoppSmartConfirmModal: typeof import('@hoppscotch/ui')['HoppSmartConfirmModal']
|
HistoryRestCard: (typeof import("./components/history/rest/Card.vue"))["default"]
|
||||||
HoppSmartExpand: typeof import('@hoppscotch/ui')['HoppSmartExpand']
|
HoppButtonPrimary: (typeof import("@hoppscotch/ui"))["HoppButtonPrimary"]
|
||||||
HoppSmartFileChip: typeof import('@hoppscotch/ui')['HoppSmartFileChip']
|
HoppButtonSecondary: (typeof import("@hoppscotch/ui"))["HoppButtonSecondary"]
|
||||||
HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput']
|
HoppSmartAnchor: (typeof import("@hoppscotch/ui"))["HoppSmartAnchor"]
|
||||||
HoppSmartIntersection: typeof import('@hoppscotch/ui')['HoppSmartIntersection']
|
HoppSmartCheckbox: (typeof import("@hoppscotch/ui"))["HoppSmartCheckbox"]
|
||||||
HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem']
|
HoppSmartConfirmModal: (typeof import("@hoppscotch/ui"))["HoppSmartConfirmModal"]
|
||||||
HoppSmartLink: typeof import('@hoppscotch/ui')['HoppSmartLink']
|
HoppSmartExpand: (typeof import("@hoppscotch/ui"))["HoppSmartExpand"]
|
||||||
HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal']
|
HoppSmartFileChip: (typeof import("@hoppscotch/ui"))["HoppSmartFileChip"]
|
||||||
HoppSmartPicture: typeof import('@hoppscotch/ui')['HoppSmartPicture']
|
HoppSmartInput: (typeof import("@hoppscotch/ui"))["HoppSmartInput"]
|
||||||
HoppSmartPlaceholder: typeof import('@hoppscotch/ui')['HoppSmartPlaceholder']
|
HoppSmartIntersection: (typeof import("@hoppscotch/ui"))["HoppSmartIntersection"]
|
||||||
HoppSmartProgressRing: typeof import('@hoppscotch/ui')['HoppSmartProgressRing']
|
HoppSmartItem: (typeof import("@hoppscotch/ui"))["HoppSmartItem"]
|
||||||
HoppSmartRadio: typeof import('@hoppscotch/ui')['HoppSmartRadio']
|
HoppSmartLink: (typeof import("@hoppscotch/ui"))["HoppSmartLink"]
|
||||||
HoppSmartRadioGroup: typeof import('@hoppscotch/ui')['HoppSmartRadioGroup']
|
HoppSmartModal: (typeof import("@hoppscotch/ui"))["HoppSmartModal"]
|
||||||
HoppSmartSelectWrapper: typeof import('@hoppscotch/ui')['HoppSmartSelectWrapper']
|
HoppSmartPicture: (typeof import("@hoppscotch/ui"))["HoppSmartPicture"]
|
||||||
HoppSmartSlideOver: typeof import('@hoppscotch/ui')['HoppSmartSlideOver']
|
HoppSmartPlaceholder: (typeof import("@hoppscotch/ui"))["HoppSmartPlaceholder"]
|
||||||
HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner']
|
HoppSmartProgressRing: (typeof import("@hoppscotch/ui"))["HoppSmartProgressRing"]
|
||||||
HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab']
|
HoppSmartRadio: (typeof import("@hoppscotch/ui"))["HoppSmartRadio"]
|
||||||
HoppSmartTabs: typeof import('@hoppscotch/ui')['HoppSmartTabs']
|
HoppSmartRadioGroup: (typeof import("@hoppscotch/ui"))["HoppSmartRadioGroup"]
|
||||||
HoppSmartToggle: typeof import('@hoppscotch/ui')['HoppSmartToggle']
|
HoppSmartSelectWrapper: (typeof import("@hoppscotch/ui"))["HoppSmartSelectWrapper"]
|
||||||
HoppSmartTree: typeof import('@hoppscotch/ui')['HoppSmartTree']
|
HoppSmartSlideOver: (typeof import("@hoppscotch/ui"))["HoppSmartSlideOver"]
|
||||||
HoppSmartWindow: typeof import('@hoppscotch/ui')['HoppSmartWindow']
|
HoppSmartSpinner: (typeof import("@hoppscotch/ui"))["HoppSmartSpinner"]
|
||||||
HoppSmartWindows: typeof import('@hoppscotch/ui')['HoppSmartWindows']
|
HoppSmartTab: (typeof import("@hoppscotch/ui"))["HoppSmartTab"]
|
||||||
HttpAuthorization: typeof import('./components/http/Authorization.vue')['default']
|
HoppSmartTabs: (typeof import("@hoppscotch/ui"))["HoppSmartTabs"]
|
||||||
HttpAuthorizationApiKey: typeof import('./components/http/authorization/ApiKey.vue')['default']
|
HoppSmartToggle: (typeof import("@hoppscotch/ui"))["HoppSmartToggle"]
|
||||||
HttpAuthorizationBasic: typeof import('./components/http/authorization/Basic.vue')['default']
|
HoppSmartTree: (typeof import("@hoppscotch/ui"))["HoppSmartTree"]
|
||||||
HttpBody: typeof import('./components/http/Body.vue')['default']
|
HoppSmartWindow: (typeof import("@hoppscotch/ui"))["HoppSmartWindow"]
|
||||||
HttpBodyParameters: typeof import('./components/http/BodyParameters.vue')['default']
|
HoppSmartWindows: (typeof import("@hoppscotch/ui"))["HoppSmartWindows"]
|
||||||
HttpCodegenModal: typeof import('./components/http/CodegenModal.vue')['default']
|
HttpAuthorization: (typeof import("./components/http/Authorization.vue"))["default"]
|
||||||
HttpHeaders: typeof import('./components/http/Headers.vue')['default']
|
HttpAuthorizationApiKey: (typeof import("./components/http/authorization/ApiKey.vue"))["default"]
|
||||||
HttpImportCurl: typeof import('./components/http/ImportCurl.vue')['default']
|
HttpAuthorizationBasic: (typeof import("./components/http/authorization/Basic.vue"))["default"]
|
||||||
HttpOAuth2Authorization: typeof import('./components/http/OAuth2Authorization.vue')['default']
|
HttpBody: (typeof import("./components/http/Body.vue"))["default"]
|
||||||
HttpParameters: typeof import('./components/http/Parameters.vue')['default']
|
HttpBodyParameters: (typeof import("./components/http/BodyParameters.vue"))["default"]
|
||||||
HttpPreRequestScript: typeof import('./components/http/PreRequestScript.vue')['default']
|
HttpCodegenModal: (typeof import("./components/http/CodegenModal.vue"))["default"]
|
||||||
HttpRawBody: typeof import('./components/http/RawBody.vue')['default']
|
HttpHeaders: (typeof import("./components/http/Headers.vue"))["default"]
|
||||||
HttpReqChangeConfirmModal: typeof import('./components/http/ReqChangeConfirmModal.vue')['default']
|
HttpImportCurl: (typeof import("./components/http/ImportCurl.vue"))["default"]
|
||||||
HttpRequest: typeof import('./components/http/Request.vue')['default']
|
HttpOAuth2Authorization: (typeof import("./components/http/OAuth2Authorization.vue"))["default"]
|
||||||
HttpRequestOptions: typeof import('./components/http/RequestOptions.vue')['default']
|
HttpParameters: (typeof import("./components/http/Parameters.vue"))["default"]
|
||||||
HttpRequestTab: typeof import('./components/http/RequestTab.vue')['default']
|
HttpPreRequestScript: (typeof import("./components/http/PreRequestScript.vue"))["default"]
|
||||||
HttpRequestVariables: typeof import('./components/http/RequestVariables.vue')['default']
|
HttpRawBody: (typeof import("./components/http/RawBody.vue"))["default"]
|
||||||
HttpResponse: typeof import('./components/http/Response.vue')['default']
|
HttpReqChangeConfirmModal: (typeof import("./components/http/ReqChangeConfirmModal.vue"))["default"]
|
||||||
HttpResponseMeta: typeof import('./components/http/ResponseMeta.vue')['default']
|
HttpRequest: (typeof import("./components/http/Request.vue"))["default"]
|
||||||
HttpSidebar: typeof import('./components/http/Sidebar.vue')['default']
|
HttpRequestOptions: (typeof import("./components/http/RequestOptions.vue"))["default"]
|
||||||
HttpTabHead: typeof import('./components/http/TabHead.vue')['default']
|
HttpRequestTab: (typeof import("./components/http/RequestTab.vue"))["default"]
|
||||||
HttpTestResult: typeof import('./components/http/TestResult.vue')['default']
|
HttpRequestVariables: (typeof import("./components/http/RequestVariables.vue"))["default"]
|
||||||
HttpTestResultEntry: typeof import('./components/http/TestResultEntry.vue')['default']
|
HttpResponse: (typeof import("./components/http/Response.vue"))["default"]
|
||||||
HttpTestResultEnv: typeof import('./components/http/TestResultEnv.vue')['default']
|
HttpResponseMeta: (typeof import("./components/http/ResponseMeta.vue"))["default"]
|
||||||
HttpTestResultReport: typeof import('./components/http/TestResultReport.vue')['default']
|
HttpSidebar: (typeof import("./components/http/Sidebar.vue"))["default"]
|
||||||
HttpTests: typeof import('./components/http/Tests.vue')['default']
|
HttpTabHead: (typeof import("./components/http/TabHead.vue"))["default"]
|
||||||
HttpURLEncodedParams: typeof import('./components/http/URLEncodedParams.vue')['default']
|
HttpTestResult: (typeof import("./components/http/TestResult.vue"))["default"]
|
||||||
IconLucideActivity: typeof import('~icons/lucide/activity')['default']
|
HttpTestResultEntry: (typeof import("./components/http/TestResultEntry.vue"))["default"]
|
||||||
IconLucideAlertTriangle: typeof import('~icons/lucide/alert-triangle')['default']
|
HttpTestResultEnv: (typeof import("./components/http/TestResultEnv.vue"))["default"]
|
||||||
IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default']
|
HttpTestResultReport: (typeof import("./components/http/TestResultReport.vue"))["default"]
|
||||||
IconLucideArrowUpRight: typeof import('~icons/lucide/arrow-up-right')['default']
|
HttpTests: (typeof import("./components/http/Tests.vue"))["default"]
|
||||||
IconLucideCheckCircle: typeof import('~icons/lucide/check-circle')['default']
|
HttpURLEncodedParams: (typeof import("./components/http/URLEncodedParams.vue"))["default"]
|
||||||
IconLucideChevronRight: typeof import('~icons/lucide/chevron-right')['default']
|
IconLucideActivity: (typeof import("~icons/lucide/activity"))["default"]
|
||||||
IconLucideGlobe: typeof import('~icons/lucide/globe')['default']
|
IconLucideAlertTriangle: (typeof import("~icons/lucide/alert-triangle"))["default"]
|
||||||
IconLucideHelpCircle: typeof import('~icons/lucide/help-circle')['default']
|
IconLucideArrowLeft: (typeof import("~icons/lucide/arrow-left"))["default"]
|
||||||
IconLucideInbox: typeof import('~icons/lucide/inbox')['default']
|
IconLucideArrowUpRight: (typeof import("~icons/lucide/arrow-up-right"))["default"]
|
||||||
IconLucideInfo: typeof import('~icons/lucide/info')['default']
|
IconLucideBrush: (typeof import("~icons/lucide/brush"))["default"]
|
||||||
IconLucideLayers: typeof import('~icons/lucide/layers')['default']
|
IconLucideCheckCircle: (typeof import("~icons/lucide/check-circle"))["default"]
|
||||||
IconLucideListEnd: typeof import('~icons/lucide/list-end')['default']
|
IconLucideChevronRight: (typeof import("~icons/lucide/chevron-right"))["default"]
|
||||||
IconLucideMinus: typeof import('~icons/lucide/minus')['default']
|
IconLucideGlobe: (typeof import("~icons/lucide/globe"))["default"]
|
||||||
IconLucideSearch: typeof import('~icons/lucide/search')['default']
|
IconLucideHelpCircle: (typeof import("~icons/lucide/help-circle"))["default"]
|
||||||
IconLucideUsers: typeof import('~icons/lucide/users')['default']
|
IconLucideInbox: (typeof import("~icons/lucide/inbox"))["default"]
|
||||||
IconLucideX: typeof import('~icons/lucide/x')['default']
|
IconLucideInfo: (typeof import("~icons/lucide/info"))["default"]
|
||||||
ImportExportBase: typeof import('./components/importExport/Base.vue')['default']
|
IconLucideLayers: (typeof import("~icons/lucide/layers"))["default"]
|
||||||
ImportExportImportExportList: typeof import('./components/importExport/ImportExportList.vue')['default']
|
IconLucideListEnd: (typeof import("~icons/lucide/list-end"))["default"]
|
||||||
ImportExportImportExportSourcesList: typeof import('./components/importExport/ImportExportSourcesList.vue')['default']
|
IconLucideMinus: (typeof import("~icons/lucide/minus"))["default"]
|
||||||
ImportExportImportExportStepsFileImport: typeof import('./components/importExport/ImportExportSteps/FileImport.vue')['default']
|
IconLucideRss: (typeof import("~icons/lucide/rss"))["default"]
|
||||||
ImportExportImportExportStepsMyCollectionImport: typeof import('./components/importExport/ImportExportSteps/MyCollectionImport.vue')['default']
|
IconLucideSearch: (typeof import("~icons/lucide/search"))["default"]
|
||||||
ImportExportImportExportStepsUrlImport: typeof import('./components/importExport/ImportExportSteps/UrlImport.vue')['default']
|
IconLucideUsers: (typeof import("~icons/lucide/users"))["default"]
|
||||||
InterceptorsErrorPlaceholder: typeof import('./components/interceptors/ErrorPlaceholder.vue')['default']
|
IconLucideVerified: (typeof import("~icons/lucide/verified"))["default"]
|
||||||
InterceptorsExtensionSubtitle: typeof import('./components/interceptors/ExtensionSubtitle.vue')['default']
|
IconLucideX: (typeof import("~icons/lucide/x"))["default"]
|
||||||
LensesHeadersRenderer: typeof import('./components/lenses/HeadersRenderer.vue')['default']
|
ImportExportBase: (typeof import("./components/importExport/Base.vue"))["default"]
|
||||||
LensesHeadersRendererEntry: typeof import('./components/lenses/HeadersRendererEntry.vue')['default']
|
ImportExportImportExportList: (typeof import("./components/importExport/ImportExportList.vue"))["default"]
|
||||||
LensesRenderersAudioLensRenderer: typeof import('./components/lenses/renderers/AudioLensRenderer.vue')['default']
|
ImportExportImportExportSourcesList: (typeof import("./components/importExport/ImportExportSourcesList.vue"))["default"]
|
||||||
LensesRenderersHTMLLensRenderer: typeof import('./components/lenses/renderers/HTMLLensRenderer.vue')['default']
|
ImportExportImportExportStepsFileImport: (typeof import("./components/importExport/ImportExportSteps/FileImport.vue"))["default"]
|
||||||
LensesRenderersImageLensRenderer: typeof import('./components/lenses/renderers/ImageLensRenderer.vue')['default']
|
ImportExportImportExportStepsMyCollectionImport: (typeof import("./components/importExport/ImportExportSteps/MyCollectionImport.vue"))["default"]
|
||||||
LensesRenderersJSONLensRenderer: typeof import('./components/lenses/renderers/JSONLensRenderer.vue')['default']
|
ImportExportImportExportStepsUrlImport: (typeof import("./components/importExport/ImportExportSteps/UrlImport.vue"))["default"]
|
||||||
LensesRenderersPDFLensRenderer: typeof import('./components/lenses/renderers/PDFLensRenderer.vue')['default']
|
InterceptorsErrorPlaceholder: (typeof import("./components/interceptors/ErrorPlaceholder.vue"))["default"]
|
||||||
LensesRenderersRawLensRenderer: typeof import('./components/lenses/renderers/RawLensRenderer.vue')['default']
|
InterceptorsExtensionSubtitle: (typeof import("./components/interceptors/ExtensionSubtitle.vue"))["default"]
|
||||||
LensesRenderersVideoLensRenderer: typeof import('./components/lenses/renderers/VideoLensRenderer.vue')['default']
|
LensesHeadersRenderer: (typeof import("./components/lenses/HeadersRenderer.vue"))["default"]
|
||||||
LensesRenderersXMLLensRenderer: typeof import('./components/lenses/renderers/XMLLensRenderer.vue')['default']
|
LensesHeadersRendererEntry: (typeof import("./components/lenses/HeadersRendererEntry.vue"))["default"]
|
||||||
LensesResponseBodyRenderer: typeof import('./components/lenses/ResponseBodyRenderer.vue')['default']
|
LensesRenderersAudioLensRenderer: (typeof import("./components/lenses/renderers/AudioLensRenderer.vue"))["default"]
|
||||||
ProfileUserDelete: typeof import('./components/profile/UserDelete.vue')['default']
|
LensesRenderersHTMLLensRenderer: (typeof import("./components/lenses/renderers/HTMLLensRenderer.vue"))["default"]
|
||||||
RealtimeCommunication: typeof import('./components/realtime/Communication.vue')['default']
|
LensesRenderersImageLensRenderer: (typeof import("./components/lenses/renderers/ImageLensRenderer.vue"))["default"]
|
||||||
RealtimeConnectionConfig: typeof import('./components/realtime/ConnectionConfig.vue')['default']
|
LensesRenderersJSONLensRenderer: (typeof import("./components/lenses/renderers/JSONLensRenderer.vue"))["default"]
|
||||||
RealtimeLog: typeof import('./components/realtime/Log.vue')['default']
|
LensesRenderersPDFLensRenderer: (typeof import("./components/lenses/renderers/PDFLensRenderer.vue"))["default"]
|
||||||
RealtimeLogEntry: typeof import('./components/realtime/LogEntry.vue')['default']
|
LensesRenderersRawLensRenderer: (typeof import("./components/lenses/renderers/RawLensRenderer.vue"))["default"]
|
||||||
RealtimeSubscription: typeof import('./components/realtime/Subscription.vue')['default']
|
LensesRenderersVideoLensRenderer: (typeof import("./components/lenses/renderers/VideoLensRenderer.vue"))["default"]
|
||||||
SettingsExtension: typeof import('./components/settings/Extension.vue')['default']
|
LensesRenderersXMLLensRenderer: (typeof import("./components/lenses/renderers/XMLLensRenderer.vue"))["default"]
|
||||||
SettingsProxy: typeof import('./components/settings/Proxy.vue')['default']
|
LensesResponseBodyRenderer: (typeof import("./components/lenses/ResponseBodyRenderer.vue"))["default"]
|
||||||
Share: typeof import('./components/share/index.vue')['default']
|
ProfileUserDelete: (typeof import("./components/profile/UserDelete.vue"))["default"]
|
||||||
ShareCreateModal: typeof import('./components/share/CreateModal.vue')['default']
|
RealtimeCommunication: (typeof import("./components/realtime/Communication.vue"))["default"]
|
||||||
ShareCustomizeModal: typeof import('./components/share/CustomizeModal.vue')['default']
|
RealtimeConnectionConfig: (typeof import("./components/realtime/ConnectionConfig.vue"))["default"]
|
||||||
ShareModal: typeof import('./components/share/Modal.vue')['default']
|
RealtimeLog: (typeof import("./components/realtime/Log.vue"))["default"]
|
||||||
ShareRequest: typeof import('./components/share/Request.vue')['default']
|
RealtimeLogEntry: (typeof import("./components/realtime/LogEntry.vue"))["default"]
|
||||||
ShareTemplatesButton: typeof import('./components/share/templates/Button.vue')['default']
|
RealtimeSubscription: (typeof import("./components/realtime/Subscription.vue"))["default"]
|
||||||
ShareTemplatesEmbeds: typeof import('./components/share/templates/Embeds.vue')['default']
|
SettingsExtension: (typeof import("./components/settings/Extension.vue"))["default"]
|
||||||
ShareTemplatesLink: typeof import('./components/share/templates/Link.vue')['default']
|
SettingsProxy: (typeof import("./components/settings/Proxy.vue"))["default"]
|
||||||
SmartAccentModePicker: typeof import('./components/smart/AccentModePicker.vue')['default']
|
Share: (typeof import("./components/share/index.vue"))["default"]
|
||||||
SmartChangeLanguage: typeof import('./components/smart/ChangeLanguage.vue')['default']
|
ShareCreateModal: (typeof import("./components/share/CreateModal.vue"))["default"]
|
||||||
SmartColorModePicker: typeof import('./components/smart/ColorModePicker.vue')['default']
|
ShareCustomizeModal: (typeof import("./components/share/CustomizeModal.vue"))["default"]
|
||||||
SmartEnvInput: typeof import('./components/smart/EnvInput.vue')['default']
|
ShareModal: (typeof import("./components/share/Modal.vue"))["default"]
|
||||||
TabPrimary: typeof import('./components/tab/Primary.vue')['default']
|
ShareRequest: (typeof import("./components/share/Request.vue"))["default"]
|
||||||
TabSecondary: typeof import('./components/tab/Secondary.vue')['default']
|
ShareTemplatesButton: (typeof import("./components/share/templates/Button.vue"))["default"]
|
||||||
Teams: typeof import('./components/teams/index.vue')['default']
|
ShareTemplatesEmbeds: (typeof import("./components/share/templates/Embeds.vue"))["default"]
|
||||||
TeamsAdd: typeof import('./components/teams/Add.vue')['default']
|
ShareTemplatesLink: (typeof import("./components/share/templates/Link.vue"))["default"]
|
||||||
TeamsEdit: typeof import('./components/teams/Edit.vue')['default']
|
SmartAccentModePicker: (typeof import("./components/smart/AccentModePicker.vue"))["default"]
|
||||||
TeamsInvite: typeof import('./components/teams/Invite.vue')['default']
|
SmartChangeLanguage: (typeof import("./components/smart/ChangeLanguage.vue"))["default"]
|
||||||
TeamsMemberStack: typeof import('./components/teams/MemberStack.vue')['default']
|
SmartColorModePicker: (typeof import("./components/smart/ColorModePicker.vue"))["default"]
|
||||||
TeamsModal: typeof import('./components/teams/Modal.vue')['default']
|
SmartEnvInput: (typeof import("./components/smart/EnvInput.vue"))["default"]
|
||||||
TeamsTeam: typeof import('./components/teams/Team.vue')['default']
|
TabPrimary: (typeof import("./components/tab/Primary.vue"))["default"]
|
||||||
Tippy: typeof import('vue-tippy')['Tippy']
|
TabSecondary: (typeof import("./components/tab/Secondary.vue"))["default"]
|
||||||
WorkspaceCurrent: typeof import('./components/workspace/Current.vue')['default']
|
Teams: (typeof import("./components/teams/index.vue"))["default"]
|
||||||
WorkspaceSelector: typeof import('./components/workspace/Selector.vue')['default']
|
TeamsAdd: (typeof import("./components/teams/Add.vue"))["default"]
|
||||||
|
TeamsEdit: (typeof import("./components/teams/Edit.vue"))["default"]
|
||||||
|
TeamsInvite: (typeof import("./components/teams/Invite.vue"))["default"]
|
||||||
|
TeamsMemberStack: (typeof import("./components/teams/MemberStack.vue"))["default"]
|
||||||
|
TeamsModal: (typeof import("./components/teams/Modal.vue"))["default"]
|
||||||
|
TeamsTeam: (typeof import("./components/teams/Team.vue"))["default"]
|
||||||
|
Tippy: (typeof import("vue-tippy"))["Tippy"]
|
||||||
|
WorkspaceCurrent: (typeof import("./components/workspace/Current.vue"))["default"]
|
||||||
|
WorkspaceSelector: (typeof import("./components/workspace/Selector.vue"))["default"]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,221 @@
|
|||||||
|
<template>
|
||||||
|
<HoppSmartModal
|
||||||
|
dialog
|
||||||
|
:title="t('access_tokens.generate_modal_title')"
|
||||||
|
@close="hideModal"
|
||||||
|
>
|
||||||
|
<template #body>
|
||||||
|
<template v-if="accessToken">
|
||||||
|
<p class="p-4 mb-4 border rounded-md text-amber-500 border-amber-600">
|
||||||
|
{{ t("access_tokens.copy_token_warning") }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-between p-4 mt-4 rounded-md bg-primaryLight"
|
||||||
|
>
|
||||||
|
<div class="text-secondaryDark">{{ accessToken }}</div>
|
||||||
|
<HoppButtonSecondary
|
||||||
|
outline
|
||||||
|
filled
|
||||||
|
:icon="copyIcon"
|
||||||
|
@click="copyAccessToken"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div v-else class="space-y-4">
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="font-semibold text-secondaryDark">
|
||||||
|
{{ t("action.label") }}
|
||||||
|
</div>
|
||||||
|
<HoppSmartInput
|
||||||
|
v-model="accessTokenLabel"
|
||||||
|
:placeholder="t('access_tokens.token_purpose')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label for="expiration" class="font-semibold text-secondaryDark">{{
|
||||||
|
t("access_tokens.expiration_label")
|
||||||
|
}}</label>
|
||||||
|
|
||||||
|
<div class="grid items-center grid-cols-2 gap-x-2">
|
||||||
|
<tippy
|
||||||
|
interactive
|
||||||
|
trigger="click"
|
||||||
|
theme="popover"
|
||||||
|
:on-shown="() => tippyActions?.focus()"
|
||||||
|
>
|
||||||
|
<HoppSmartSelectWrapper>
|
||||||
|
<input
|
||||||
|
id="expiration"
|
||||||
|
:value="expiration"
|
||||||
|
readonly
|
||||||
|
class="flex flex-1 px-4 py-2 bg-transparent border rounded cursor-pointer border-divider"
|
||||||
|
/>
|
||||||
|
</HoppSmartSelectWrapper>
|
||||||
|
|
||||||
|
<template #content="{ hide }">
|
||||||
|
<div
|
||||||
|
ref="tippyActions"
|
||||||
|
tabindex="0"
|
||||||
|
role="menu"
|
||||||
|
class="flex flex-col focus:outline-none"
|
||||||
|
@keyup.escape="hide"
|
||||||
|
>
|
||||||
|
<HoppSmartItem
|
||||||
|
v-for="expirationOption in Object.keys(expirationOptions)"
|
||||||
|
:key="expirationOption"
|
||||||
|
:label="expirationOption"
|
||||||
|
:icon="
|
||||||
|
expirationOption === expiration
|
||||||
|
? IconCircleDot
|
||||||
|
: IconCircle
|
||||||
|
"
|
||||||
|
:active="expirationOption === expiration"
|
||||||
|
:aria-selected="expirationOption === expiration"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
expiration = expirationOption
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</tippy>
|
||||||
|
|
||||||
|
<span class="text-secondaryLight">{{ expirationDateText }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="font-semibold text-secondaryDark">
|
||||||
|
{{ t("access_tokens.scope_label") }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-secondaryLight">
|
||||||
|
{{ t("access_tokens.workspace_read_only_access") }}<br />
|
||||||
|
{{ t("access_tokens.personal_workspace_access_limitation") }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<HoppButtonSecondary
|
||||||
|
v-if="accessToken"
|
||||||
|
:label="t('action.close')"
|
||||||
|
outline
|
||||||
|
filled
|
||||||
|
@click="hideModal"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div v-else class="flex items-center gap-x-2">
|
||||||
|
<HoppButtonPrimary
|
||||||
|
:loading="tokenGenerateActionLoading"
|
||||||
|
filled
|
||||||
|
outline
|
||||||
|
:label="t('access_tokens.generate_token')"
|
||||||
|
@click="generateAccessToken"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HoppButtonSecondary
|
||||||
|
:label="t('action.cancel')"
|
||||||
|
outline
|
||||||
|
filled
|
||||||
|
@click="hideModal"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</HoppSmartModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useI18n } from "@composables/i18n"
|
||||||
|
import { useToast } from "@composables/toast"
|
||||||
|
import { refAutoReset } from "@vueuse/core"
|
||||||
|
import { VNodeRef, computed, ref } from "vue"
|
||||||
|
|
||||||
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
|
import { shortDateTime } from "~/helpers/utils/date"
|
||||||
|
|
||||||
|
import IconCheck from "~icons/lucide/check"
|
||||||
|
import IconCircle from "~icons/lucide/circle"
|
||||||
|
import IconCircleDot from "~icons/lucide/circle-dot"
|
||||||
|
import IconCopy from "~icons/lucide/copy"
|
||||||
|
|
||||||
|
const t = useI18n()
|
||||||
|
const toast = useToast()
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
tokenGenerateActionLoading: boolean
|
||||||
|
accessToken: string | null
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "hide-modal"): void
|
||||||
|
(
|
||||||
|
e: "generate-access-token",
|
||||||
|
{ label, expiryInDays }: { label: string; expiryInDays: number | null }
|
||||||
|
): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// Template refs
|
||||||
|
const tippyActions = ref<VNodeRef | null>(null)
|
||||||
|
|
||||||
|
const copyIcon = refAutoReset<typeof IconCopy | typeof IconCheck>(
|
||||||
|
IconCopy,
|
||||||
|
1000
|
||||||
|
)
|
||||||
|
|
||||||
|
const accessTokenLabel = ref<string>("")
|
||||||
|
const expiration = ref<string>("30 days")
|
||||||
|
|
||||||
|
const expirationOptions: Record<string, number | null> = {
|
||||||
|
"7 days": 7,
|
||||||
|
"30 days": 30,
|
||||||
|
"60 days": 60,
|
||||||
|
"90 days": 90,
|
||||||
|
"No expiration": null,
|
||||||
|
}
|
||||||
|
|
||||||
|
const expirationDateText = computed(() => {
|
||||||
|
const chosenExpiryInDays = expirationOptions[expiration.value]
|
||||||
|
|
||||||
|
if (chosenExpiryInDays === null) {
|
||||||
|
return t("access_tokens.no_expiration_verbose")
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentDate = new Date()
|
||||||
|
currentDate.setDate(currentDate.getDate() + chosenExpiryInDays)
|
||||||
|
|
||||||
|
const expirationDate = shortDateTime(currentDate, false)
|
||||||
|
return `${t("access_tokens.token_expires_on")} ${expirationDate}`
|
||||||
|
})
|
||||||
|
|
||||||
|
const copyAccessToken = () => {
|
||||||
|
if (!props.accessToken) {
|
||||||
|
toast.error("error.something_went_wrong")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboard(props.accessToken)
|
||||||
|
copyIcon.value = IconCheck
|
||||||
|
|
||||||
|
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateAccessToken = async () => {
|
||||||
|
if (!accessTokenLabel.value) {
|
||||||
|
toast.error(t("access_tokens.invalid_label"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emit("generate-access-token", {
|
||||||
|
label: accessTokenLabel.value,
|
||||||
|
expiryInDays: expirationOptions[expiration.value],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideModal = () => emit("hide-modal")
|
||||||
|
</script>
|
||||||
128
packages/hoppscotch-common/src/components/accessTokens/List.vue
Normal file
128
packages/hoppscotch-common/src/components/accessTokens/List.vue
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="isInitialPageLoad" class="flex flex-col items-center py-3">
|
||||||
|
<HoppSmartSpinner />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-else-if="initialPageLoadHasError"
|
||||||
|
class="flex flex-col items-center py-4"
|
||||||
|
>
|
||||||
|
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||||
|
{{ t("error.something_went_wrong") }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HoppSmartPlaceholder
|
||||||
|
v-else-if="accessTokens.length === 0"
|
||||||
|
:src="`/images/states/${colorMode}/pack.svg`"
|
||||||
|
:alt="`${t('empty.access_tokens')}`"
|
||||||
|
:text="t('empty.access_tokens')"
|
||||||
|
@drop.stop
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="grid gap-4 p-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="{ id, label, lastUsedOn, expiresOn } in accessTokens"
|
||||||
|
:key="id"
|
||||||
|
class="flex flex-col items-center gap-4 p-4 border rounded border-divider"
|
||||||
|
>
|
||||||
|
<div class="w-full text-sm font-semibold truncate text-secondaryDark">
|
||||||
|
{{ label }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between w-full gap-x-4">
|
||||||
|
<div class="space-y-1 text-secondaryLight">
|
||||||
|
<div class="space-x-1">
|
||||||
|
<span class="font-semibold"
|
||||||
|
>{{ t("access_tokens.last_used_on") }}:</span
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{{ shortDateTime(lastUsedOn, false) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-x-1">
|
||||||
|
<span class="font-semibold"
|
||||||
|
>{{ t("access_tokens.expires_on") }}:</span
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{{ getTokenExpiryText(expiresOn) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HoppButtonSecondary
|
||||||
|
:label="t('action.delete')"
|
||||||
|
filled
|
||||||
|
outline
|
||||||
|
@click="
|
||||||
|
emit('delete-access-token', {
|
||||||
|
tokenId: id,
|
||||||
|
tokenLabel: label,
|
||||||
|
})
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HoppSmartIntersection
|
||||||
|
v-if="hasMoreTokens"
|
||||||
|
@intersecting="emit('fetch-more-tokens')"
|
||||||
|
>
|
||||||
|
<div v-if="loading" class="flex flex-col items-center py-3">
|
||||||
|
<HoppSmartSpinner />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else-if="hasError" class="flex flex-col items-center py-4">
|
||||||
|
<icon-lucide-help-circle class="mb-4 svg-icons" />
|
||||||
|
{{ t("error.something_went_wrong") }}
|
||||||
|
</div>
|
||||||
|
</HoppSmartIntersection>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useI18n } from "@composables/i18n"
|
||||||
|
import { useColorMode } from "@vueuse/core"
|
||||||
|
import { computed } from "vue"
|
||||||
|
|
||||||
|
import { shortDateTime } from "~/helpers/utils/date"
|
||||||
|
import { AccessToken } from "./index.vue"
|
||||||
|
|
||||||
|
const colorMode = useColorMode()
|
||||||
|
const t = useI18n()
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
accessTokens: AccessToken[]
|
||||||
|
hasMoreTokens: boolean
|
||||||
|
loading: boolean
|
||||||
|
hasError: boolean
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "fetch-more-tokens"): void
|
||||||
|
(
|
||||||
|
e: "delete-access-token",
|
||||||
|
{ tokenId, tokenLabel }: { tokenId: string; tokenLabel: string }
|
||||||
|
): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const isInitialPageLoad = computed(() => props.loading && !props.hasMoreTokens)
|
||||||
|
const initialPageLoadHasError = computed(
|
||||||
|
() => props.hasError && !props.hasMoreTokens
|
||||||
|
)
|
||||||
|
|
||||||
|
const getTokenExpiryText = (tokenExpiresOn: string | null) => {
|
||||||
|
if (!tokenExpiresOn) {
|
||||||
|
return t("access_tokens.no_expiration")
|
||||||
|
}
|
||||||
|
|
||||||
|
const isTokenExpired = new Date(tokenExpiresOn).toISOString() > tokenExpiresOn
|
||||||
|
|
||||||
|
return isTokenExpired
|
||||||
|
? t("access_tokens.expired")
|
||||||
|
: shortDateTime(tokenExpiresOn, false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-4 space-y-4">
|
||||||
|
<div class="space-y-1">
|
||||||
|
<h4 class="font-semibold text-secondaryDark">
|
||||||
|
{{ t("access_tokens.section_title") }}
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p class="text-secondaryLight">
|
||||||
|
{{ t("access_tokens.section_description") }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HoppButtonSecondary
|
||||||
|
filled
|
||||||
|
outline
|
||||||
|
:label="t('access_tokens.generate_new_token')"
|
||||||
|
@click="emit('show-access-tokens-generate-modal')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useI18n } from "~/composables/i18n"
|
||||||
|
|
||||||
|
const t = useI18n()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "show-access-tokens-generate-modal"): void
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
208
packages/hoppscotch-common/src/components/accessTokens/index.vue
Normal file
208
packages/hoppscotch-common/src/components/accessTokens/index.vue
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
<template>
|
||||||
|
<AccessTokensOverview
|
||||||
|
@show-access-tokens-generate-modal="showAccessTokensGenerateModal = true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AccessTokensList
|
||||||
|
:access-tokens="accessTokens"
|
||||||
|
:has-error="tokensListFetchErrored"
|
||||||
|
:has-more-tokens="hasMoreTokens"
|
||||||
|
:loading="tokensListLoading"
|
||||||
|
@delete-access-token="displayDeleteAccessTokenConfirmationModal"
|
||||||
|
@fetch-more-tokens="fetchAccessTokens"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AccessTokensGenerateModal
|
||||||
|
v-if="showAccessTokensGenerateModal"
|
||||||
|
:access-token="accessToken"
|
||||||
|
:token-generate-action-loading="tokenGenerateActionLoading"
|
||||||
|
@generate-access-token="generateAccessToken"
|
||||||
|
@hide-modal="hideAccessTokenGenerateModal"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<HoppSmartConfirmModal
|
||||||
|
:show="confirmDeleteAccessToken"
|
||||||
|
:loading-state="tokenDeleteActionLoading"
|
||||||
|
:title="
|
||||||
|
t('confirm.delete_access_token', { tokenLabel: tokenToDelete?.label })
|
||||||
|
"
|
||||||
|
@hide-modal="confirmDeleteAccessToken = false"
|
||||||
|
@resolve="deleteAccessToken"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import axios from "axios"
|
||||||
|
import { Ref, onMounted, ref } from "vue"
|
||||||
|
import { platform } from "~/platform"
|
||||||
|
|
||||||
|
import { useI18n } from "@composables/i18n"
|
||||||
|
import { useToast } from "@composables/toast"
|
||||||
|
|
||||||
|
export type AccessToken = {
|
||||||
|
id: string
|
||||||
|
label: string
|
||||||
|
createdOn: string
|
||||||
|
lastUsedOn: string
|
||||||
|
expiresOn: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const t = useI18n()
|
||||||
|
const toast = useToast()
|
||||||
|
|
||||||
|
const confirmDeleteAccessToken = ref(false)
|
||||||
|
const hasMoreTokens = ref(false)
|
||||||
|
const showAccessTokensGenerateModal = ref(false)
|
||||||
|
const tokenDeleteActionLoading = ref(false)
|
||||||
|
const tokenGenerateActionLoading = ref(false)
|
||||||
|
const tokensListFetchErrored = ref(false)
|
||||||
|
const tokensListLoading = ref(false)
|
||||||
|
|
||||||
|
const accessToken: Ref<string | null> = ref(null)
|
||||||
|
const tokenToDelete = ref<{ id: string; label: string } | null>(null)
|
||||||
|
|
||||||
|
const accessTokens: Ref<AccessToken[]> = ref([])
|
||||||
|
|
||||||
|
const limit = 12
|
||||||
|
let offset = 0
|
||||||
|
|
||||||
|
const endpointPrefix = `${import.meta.env.VITE_BACKEND_API_URL}/access-tokens`
|
||||||
|
|
||||||
|
const getAxiosPlatformConfig = async () => {
|
||||||
|
await platform.auth.waitProbableLoginToConfirm()
|
||||||
|
return platform.auth.axiosPlatformConfig?.() ?? {}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchAccessTokens()
|
||||||
|
})
|
||||||
|
|
||||||
|
const fetchAccessTokens = async () => {
|
||||||
|
tokensListLoading.value = true
|
||||||
|
|
||||||
|
const axiosConfig = await getAxiosPlatformConfig()
|
||||||
|
const endpoint = `${endpointPrefix}/list?offset=${offset}&limit=${limit}`
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { data } = await axios.get(endpoint, axiosConfig)
|
||||||
|
|
||||||
|
accessTokens.value.push(...data)
|
||||||
|
|
||||||
|
if (data.length > 0) {
|
||||||
|
offset += data.length
|
||||||
|
}
|
||||||
|
|
||||||
|
hasMoreTokens.value = data.length === limit
|
||||||
|
|
||||||
|
if (tokensListFetchErrored.value) {
|
||||||
|
tokensListFetchErrored.value = false
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
toast.error(t("error.fetching_access_tokens_list"))
|
||||||
|
tokensListFetchErrored.value = true
|
||||||
|
} finally {
|
||||||
|
tokensListLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateAccessToken = async ({
|
||||||
|
label,
|
||||||
|
expiryInDays,
|
||||||
|
}: {
|
||||||
|
label: string
|
||||||
|
expiryInDays: number | null
|
||||||
|
}) => {
|
||||||
|
tokenGenerateActionLoading.value = true
|
||||||
|
|
||||||
|
const axiosConfig = await getAxiosPlatformConfig()
|
||||||
|
const endpoint = `${endpointPrefix}/create`
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
label,
|
||||||
|
expiryInDays,
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { data }: { data: { token: string; info: AccessToken } } =
|
||||||
|
await axios.post(endpoint, body, axiosConfig)
|
||||||
|
|
||||||
|
accessTokens.value.unshift(data.info)
|
||||||
|
accessToken.value = data.token
|
||||||
|
|
||||||
|
// Incrementing the offset value by 1 to account for the newly generated token
|
||||||
|
offset += 1
|
||||||
|
|
||||||
|
// Toggle the error state in case it was set
|
||||||
|
if (tokensListFetchErrored.value) {
|
||||||
|
tokensListFetchErrored.value = false
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
toast.error(t("error.generate_access_token"))
|
||||||
|
showAccessTokensGenerateModal.value = false
|
||||||
|
} finally {
|
||||||
|
tokenGenerateActionLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteAccessToken = async () => {
|
||||||
|
if (tokenToDelete.value === null) {
|
||||||
|
toast.error(t("error.something_went_wrong"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id: tokenIdToDelete, label: tokenLabelToDelete } = tokenToDelete.value
|
||||||
|
|
||||||
|
tokenDeleteActionLoading.value = true
|
||||||
|
|
||||||
|
const axiosConfig = await getAxiosPlatformConfig()
|
||||||
|
const endpoint = `${endpointPrefix}/revoke?id=${tokenIdToDelete}`
|
||||||
|
|
||||||
|
try {
|
||||||
|
await axios.delete(endpoint, axiosConfig)
|
||||||
|
|
||||||
|
accessTokens.value = accessTokens.value.filter(
|
||||||
|
(token) => token.id !== tokenIdToDelete
|
||||||
|
)
|
||||||
|
|
||||||
|
// Decreasing the offset value by 1 to account for the deleted token
|
||||||
|
offset = offset > 0 ? offset - 1 : offset
|
||||||
|
|
||||||
|
toast.success(
|
||||||
|
t("access_tokens.deletion_success", { label: tokenLabelToDelete })
|
||||||
|
)
|
||||||
|
|
||||||
|
// Toggle the error state in case it was set
|
||||||
|
if (tokensListFetchErrored.value) {
|
||||||
|
tokensListFetchErrored.value = false
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
toast.error(t("error.delete_access_token"))
|
||||||
|
} finally {
|
||||||
|
tokenDeleteActionLoading.value = false
|
||||||
|
confirmDeleteAccessToken.value = false
|
||||||
|
|
||||||
|
tokenToDelete.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideAccessTokenGenerateModal = () => {
|
||||||
|
// Reset the reactive state variable holding access token value and hide the modal
|
||||||
|
accessToken.value = null
|
||||||
|
showAccessTokensGenerateModal.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayDeleteAccessTokenConfirmationModal = ({
|
||||||
|
tokenId,
|
||||||
|
tokenLabel,
|
||||||
|
}: {
|
||||||
|
tokenId: string
|
||||||
|
tokenLabel: string
|
||||||
|
}) => {
|
||||||
|
confirmDeleteAccessToken.value = true
|
||||||
|
|
||||||
|
tokenToDelete.value = {
|
||||||
|
id: tokenId,
|
||||||
|
label: tokenLabel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,10 +1,17 @@
|
|||||||
export function shortDateTime(date: string | number | Date) {
|
export function shortDateTime(
|
||||||
|
date: string | number | Date,
|
||||||
|
includeTime: boolean = true
|
||||||
|
) {
|
||||||
return new Date(date).toLocaleString("en-US", {
|
return new Date(date).toLocaleString("en-US", {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "short",
|
month: "short",
|
||||||
day: "numeric",
|
day: "numeric",
|
||||||
hour: "numeric",
|
...(includeTime
|
||||||
minute: "numeric",
|
? {
|
||||||
second: "numeric",
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
second: "numeric",
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
styles="sticky overflow-x-auto flex-shrink-0 bg-primary top-0 z-10"
|
styles="sticky overflow-x-auto flex-shrink-0 bg-primary top-0 z-10"
|
||||||
render-inactive-tabs
|
render-inactive-tabs
|
||||||
>
|
>
|
||||||
<HoppSmartTab :id="'sync'" :label="t('settings.account')">
|
<HoppSmartTab id="sync" :label="t('settings.account')">
|
||||||
<div class="grid grid-cols-1">
|
<div class="grid grid-cols-1">
|
||||||
<section class="p-4">
|
<section class="p-4">
|
||||||
<h4 class="font-semibold text-secondaryDark">
|
<h4 class="font-semibold text-secondaryDark">
|
||||||
@@ -177,14 +177,17 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<ProfileShortcodes />
|
|
||||||
|
|
||||||
<ProfileUserDelete />
|
<ProfileUserDelete />
|
||||||
</div>
|
</div>
|
||||||
</HoppSmartTab>
|
</HoppSmartTab>
|
||||||
<HoppSmartTab :id="'teams'" :label="t('team.title')">
|
|
||||||
|
<HoppSmartTab id="teams" :label="t('team.title')">
|
||||||
<Teams :modal="false" class="p-4" />
|
<Teams :modal="false" class="p-4" />
|
||||||
</HoppSmartTab>
|
</HoppSmartTab>
|
||||||
|
|
||||||
|
<HoppSmartTab id="tokens" :label="t('access_tokens.tab_title')">
|
||||||
|
<AccessTokens />
|
||||||
|
</HoppSmartTab>
|
||||||
</HoppSmartTabs>
|
</HoppSmartTabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -193,24 +196,23 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watchEffect, computed } from "vue"
|
import * as E from "fp-ts/Either"
|
||||||
|
import { computed, ref, watchEffect } from "vue"
|
||||||
|
|
||||||
import { platform } from "~/platform"
|
import { platform } from "~/platform"
|
||||||
|
|
||||||
import { invokeAction } from "~/helpers/actions"
|
|
||||||
import { useReadonlyStream } from "@composables/stream"
|
|
||||||
import { useI18n } from "@composables/i18n"
|
|
||||||
import { useToast } from "@composables/toast"
|
|
||||||
import { useSetting } from "@composables/settings"
|
|
||||||
import { useColorMode } from "@composables/theming"
|
|
||||||
import { usePageHead } from "@composables/head"
|
import { usePageHead } from "@composables/head"
|
||||||
|
import { useI18n } from "@composables/i18n"
|
||||||
|
import { useSetting } from "@composables/settings"
|
||||||
|
import { useReadonlyStream } from "@composables/stream"
|
||||||
|
import { useColorMode } from "@composables/theming"
|
||||||
|
import { useToast } from "@composables/toast"
|
||||||
|
import { invokeAction } from "~/helpers/actions"
|
||||||
|
|
||||||
import { toggleSetting } from "~/newstore/settings"
|
import { toggleSetting } from "~/newstore/settings"
|
||||||
|
|
||||||
import IconVerified from "~icons/lucide/verified"
|
|
||||||
import IconSettings from "~icons/lucide/settings"
|
import IconSettings from "~icons/lucide/settings"
|
||||||
|
import IconVerified from "~icons/lucide/verified"
|
||||||
import * as E from "fp-ts/Either"
|
|
||||||
|
|
||||||
type ProfileTabs = "sync" | "teams"
|
type ProfileTabs = "sync" | "teams"
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ export type AuthPlatformDef = {
|
|||||||
* called by the platform to provide additional/different config options when
|
* called by the platform to provide additional/different config options when
|
||||||
* sending requests with axios
|
* sending requests with axios
|
||||||
* eg: SH needs to include cookies in the request, while Central doesn't and throws a cors error if it does
|
* eg: SH needs to include cookies in the request, while Central doesn't and throws a cors error if it does
|
||||||
|
* Ensure to invoke `platform.auth.waitProbableLoginToConfirm()` before accessing
|
||||||
*
|
*
|
||||||
* @returns AxiosRequestConfig
|
* @returns AxiosRequestConfig
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user