feat: (authentication) Api key based authentication [#2000] (#2021)

Co-authored-by: Liyas Thomas <liyascthomas@gmail.com>
This commit is contained in:
Edwin Fajardo
2021-12-17 10:02:29 -06:00
committed by GitHub
parent 156011f2cd
commit f174086281
3 changed files with 122 additions and 12 deletions

View File

@@ -70,6 +70,18 @@
$refs.authTypeOptions.tippy().hide() $refs.authTypeOptions.tippy().hide()
" "
/> />
<SmartItem
label="API key"
:icon="
authName === 'API key'
? 'radio_button_checked'
: 'radio_button_unchecked'
"
@click.native="
authType = 'api-key'
$refs.authTypeOptions.tippy().hide()
"
/>
</tippy> </tippy>
</span> </span>
<div class="flex"> <div class="flex">
@@ -213,6 +225,77 @@
</div> </div>
</div> </div>
</div> </div>
<div
v-if="authType === 'api-key'"
class="border-b border-dividerLight flex"
>
<div class="border-r border-dividerLight w-2/3">
<div class="border-b border-dividerLight flex">
<SmartEnvInput
v-model="apiKey"
placeholder="Key"
styles="bg-transparent flex flex-1 py-1 px-4"
/>
</div>
<div class="border-b border-dividerLight flex">
<SmartEnvInput
v-model="apiValue"
placeholder="Value"
styles="bg-transparent flex flex-1 py-1 px-4"
/>
</div>
<div class="border-b border-dividerLight flex items-center">
<label class="text-secondaryLight ml-4">
{{ $t("authorization.pass_key_by") }}
</label>
<tippy
ref="addToOptions"
interactive
trigger="click"
theme="popover"
arrow
>
<template #trigger>
<span class="select-wrapper">
<ButtonSecondary
:label="addTo || 'Header'"
class="rounded-none ml-2 pr-8"
/>
</span>
</template>
<SmartItem
:label="'Header'"
@click.native="
addTo = 'Header'
$refs.addToOptions.tippy().hide()
"
/>
<SmartItem
:label="'Query params'"
@click.native="
addTo = 'Query params'
$refs.addToOptions.tippy().hide()
"
/>
</tippy>
</div>
</div>
<div
class="bg-primary h-full top-upperTertiaryStickyFold min-w-46 max-w-1/3 p-4 z-9 sticky overflow-auto"
>
<div class="p-2">
<div class="text-secondaryLight pb-2">
{{ $t("helpers.authorization") }}
</div>
<SmartAnchor
class="link"
:label="`${$t('authorization.learn')} \xA0 →`"
to="https://docs.hoppscotch.io/features/authorization"
blank
/>
</div>
</div>
</div>
</div> </div>
</template> </template>
@@ -222,6 +305,7 @@ import {
HoppRESTAuthBasic, HoppRESTAuthBasic,
HoppRESTAuthBearer, HoppRESTAuthBearer,
HoppRESTAuthOAuth2, HoppRESTAuthOAuth2,
HoppRESTAuthApiKey,
} from "@hoppscotch/data" } from "@hoppscotch/data"
import { pluckRef, useStream } from "~/helpers/utils/composables" import { pluckRef, useStream } from "~/helpers/utils/composables"
import { restAuth$, setRESTAuth } from "~/newstore/RESTSession" import { restAuth$, setRESTAuth } from "~/newstore/RESTSession"
@@ -239,6 +323,7 @@ export default defineComponent({
if (authType.value === "basic") return "Basic Auth" if (authType.value === "basic") return "Basic Auth"
else if (authType.value === "bearer") return "Bearer" else if (authType.value === "bearer") return "Bearer"
else if (authType.value === "oauth-2") return "OAuth 2.0" else if (authType.value === "oauth-2") return "OAuth 2.0"
else if (authType.value === "api-key") return "API key"
else return "None" else return "None"
}) })
const authActive = pluckRef(auth, "authActive") const authActive = pluckRef(auth, "authActive")
@@ -246,6 +331,9 @@ export default defineComponent({
const basicPassword = pluckRef(auth as Ref<HoppRESTAuthBasic>, "password") const basicPassword = pluckRef(auth as Ref<HoppRESTAuthBasic>, "password")
const bearerToken = pluckRef(auth as Ref<HoppRESTAuthBearer>, "token") const bearerToken = pluckRef(auth as Ref<HoppRESTAuthBearer>, "token")
const oauth2Token = pluckRef(auth as Ref<HoppRESTAuthOAuth2>, "token") const oauth2Token = pluckRef(auth as Ref<HoppRESTAuthOAuth2>, "token")
const apiKey = pluckRef(auth as Ref<HoppRESTAuthApiKey>, "key")
const apiValue = pluckRef(auth as Ref<HoppRESTAuthApiKey>, "value")
const addTo = pluckRef(auth as Ref<HoppRESTAuthApiKey>, "addTo")
const URLExcludes = useSetting("URL_EXCLUDES") const URLExcludes = useSetting("URL_EXCLUDES")
const clearContent = () => { const clearContent = () => {
auth.value = { auth.value = {
@@ -264,6 +352,9 @@ export default defineComponent({
oauth2Token, oauth2Token,
URLExcludes, URLExcludes,
clearContent, clearContent,
apiKey,
apiValue,
addTo,
} }
}, },
}) })

View File

@@ -76,6 +76,18 @@ export function getEffectiveRESTRequest(
value: parseTemplateString(x.value, envVariables), value: parseTemplateString(x.value, envVariables),
})) }))
const effectiveFinalParams = request.params
.filter(
(x) =>
x.key !== "" && // Remove empty keys
x.active // Only active
)
.map((x) => ({
active: true,
key: parseTemplateString(x.key, envVariables),
value: parseTemplateString(x.value, envVariables),
}))
// Authentication // Authentication
if (request.auth.authActive) { if (request.auth.authActive) {
// TODO: Support a better b64 implementation than btoa ? // TODO: Support a better b64 implementation than btoa ?
@@ -100,6 +112,22 @@ export function getEffectiveRESTRequest(
envVariables envVariables
)}`, )}`,
}) })
} else if (request.auth.authType === "api-key") {
const { key, value, addTo } = request.auth
if (addTo === "Header") {
effectiveFinalHeaders.push({
active: true,
key: parseTemplateString(key, envVariables),
value: parseTemplateString(value, envVariables),
})
} else if (addTo === "Query params") {
effectiveFinalParams.push({
active: true,
key: parseTemplateString(key, envVariables),
value: parseTemplateString(value, envVariables),
})
}
} }
} }
@@ -115,17 +143,7 @@ export function getEffectiveRESTRequest(
...request, ...request,
effectiveFinalURL: parseTemplateString(request.endpoint, envVariables), effectiveFinalURL: parseTemplateString(request.endpoint, envVariables),
effectiveFinalHeaders, effectiveFinalHeaders,
effectiveFinalParams: request.params effectiveFinalParams,
.filter(
(x) =>
x.key !== "" && // Remove empty keys
x.active // Only active
)
.map((x) => ({
active: true,
key: parseTemplateString(x.key, envVariables),
value: parseTemplateString(x.value, envVariables),
})),
effectiveFinalBody, effectiveFinalBody,
} }
} }

View File

@@ -96,7 +96,8 @@
"password": "Password", "password": "Password",
"token": "Token", "token": "Token",
"type": "Authorization Type", "type": "Authorization Type",
"username": "Username" "username": "Username",
"pass_key_by": "Pass by"
}, },
"collection": { "collection": {
"created": "Collection created", "created": "Collection created",