├── .eslintignore
├── .eslintrc.cjs
├── .github
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── FUNDING.yaml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc
├── README.md
├── package-lock.json
├── package.json
├── playwright.config.ts
├── src
├── app.d.ts
├── app.html
├── lib
│ ├── components
│ │ ├── AuthorizerBasicAuthLogin.svelte
│ │ ├── AuthorizerForgotPassword.svelte
│ │ ├── AuthorizerMagicLinkLogin.svelte
│ │ ├── AuthorizerProvider.svelte
│ │ ├── AuthorizerResetPassword.svelte
│ │ ├── AuthorizerRoot.svelte
│ │ ├── AuthorizerSignup.svelte
│ │ ├── AuthorizerSocialLogin.svelte
│ │ ├── AuthorizerVerifyOtp.svelte
│ │ ├── Message.svelte
│ │ └── PasswordStrengthIndicator.svelte
│ ├── constants
│ │ └── index.ts
│ ├── icons
│ │ ├── Apple.svelte
│ │ ├── Close.svelte
│ │ ├── Facebook.svelte
│ │ ├── Github.svelte
│ │ ├── Google.svelte
│ │ ├── Linkedin.svelte
│ │ ├── Microsoft.svelte
│ │ ├── Twitter.svelte
│ │ └── index.ts
│ ├── index.ts
│ ├── store
│ │ └── index.ts
│ ├── styledComponents
│ │ ├── StyledButton.svelte
│ │ ├── StyledFlex.svelte
│ │ ├── StyledFooter.svelte
│ │ ├── StyledFormGroup.svelte
│ │ ├── StyledLink.svelte
│ │ ├── StyledMessageWrapper.svelte
│ │ ├── StyledPasswordStrength.svelte
│ │ ├── StyledPasswordStrengthWrapper.svelte
│ │ ├── StyledSeparator.svelte
│ │ ├── StyledWrapper.svelte
│ │ └── index.ts
│ ├── styles
│ │ └── default.css
│ ├── types
│ │ └── index.ts
│ └── utils
│ │ ├── common.ts
│ │ ├── url.ts
│ │ └── window.ts
└── routes
│ ├── +layout.svelte
│ ├── +page.svelte
│ └── reset-password
│ └── +page.svelte
├── static
└── favicon.png
├── svelte.config.js
├── tsconfig.json
└── vite.config.ts
/.eslintignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: '@typescript-eslint/parser',
4 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
5 | plugins: ['svelte3', '@typescript-eslint'],
6 | ignorePatterns: ['*.cjs'],
7 | overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
8 | settings: {
9 | 'svelte3/typescript': () => require('typescript')
10 | },
11 | parserOptions: {
12 | sourceType: 'module',
13 | ecmaVersion: 2020
14 | },
15 | env: {
16 | browser: true,
17 | es2017: true,
18 | node: true
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | We're so excited you're interested in helping with Authorizer! We are happy to help you get started, even if you don't have any previous open-source experience :blush:
4 |
5 | ## New to Open Source?
6 |
7 | 1. Take a look at [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)
8 | 2. Go through the [Authorizer Code of Conduct](https://github.com/authorizerdev/authorizer-svelete/blob/main/.github/CODE_OF_CONDUCT.md)
9 |
10 | ## Where to ask questions?
11 |
12 | 1. Check our [Github Issues](https://github.com/authorizerdev/authorizer/issues) to see if someone has already answered your question.
13 | 2. Join our community on [Discord](https://discord.gg/Zv2D5h6kkK) and feel free to ask us your questions
14 |
15 | As you gain experience with Authorizer, please help answer other people's questions! :pray:
16 |
17 | ## What to work on?
18 |
19 | You can get started by taking a look at our [Github issues](https://github.com/authorizerdev/authorizer-svelte/issues)
20 | If you find one that looks interesting and no one else is already working on it, comment on that issue and start contributing 🙂.
21 |
22 | Please ask as many questions as you need, either directly in the issue or on [Discord](https://discord.gg/Zv2D5h6kkK). We're happy to help!:raised_hands:
23 |
24 | ### Contributions that are ALWAYS welcome
25 |
26 | 1. More tests
27 | 2. Improved Docs
28 | 3. Improved error messages
29 | 4. Educational content like blogs, videos, courses
30 |
31 | ## Development Setup
32 |
33 | ### Prerequisites
34 |
35 | - OS: Linux or macOS or windows
36 | - NodeJS: >= v16.17.1
37 |
38 | ### Familiarize yourself with Authorizer
39 |
40 | 1. [Architecture of Authorizer](http://docs.authorizer.dev/)
41 | 2. [GraphQL APIs](https://docs.authorizer.dev/core/graphql-api/)
42 | 3. [authorizer-js](https://docs.authorizer.dev/authorizer-js). authorizer-js is used under the hood to make requests to authorizer server.
43 |
44 | ### Project Setup for Authorizer svelte
45 |
46 | 1. Fork the [authorizer](https://github.com/authorizerdev/authorizer-svelte) repository (**Skip this step if you have access to repo**)
47 | 2. Clone repo: `git clone https://github.com/authorizerdev/authorizer-svelte.git` or use the forked url from step 1
48 | 3. Change directory to authorizer: `cd authorizer-svelte`
49 | 4. Install dependencies `npm install` or `yarn`
50 | 5. Update authorizer URL in `src/routes/+layout.svelte` if you are not using local instance of authorizer.
51 | 6. Make necessary changes in `src/lib`
52 | 7. Run in development mode `npm run dev` or `yarn dev`
53 |
--------------------------------------------------------------------------------
/.github/FUNDING.yaml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: authorizerdev
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 | ---
8 |
9 | **Version:** x.y.z
10 |
11 |
12 |
13 | **Describe the bug**
14 |
15 |
16 |
17 | **Steps To Reproduce**
18 |
19 |
20 |
21 | **Expected behavior**
22 |
23 |
24 |
25 | **Screenshots**
26 |
27 |
28 |
29 | **Desktop (please complete the following information):**
30 |
31 | - OS: [e.g. iOS]
32 | - Browser [e.g. chrome, safari]
33 | - Version [e.g. 22]
34 |
35 | **Additional context**
36 |
37 |
38 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea or enhancement for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 | ---
8 |
9 | **Feature Description**
10 |
11 |
12 |
13 | **Describe the solution you'd like**
14 |
15 |
16 |
17 | **Describe alternatives you've considered**
18 |
19 |
20 |
21 | **Additional context**
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | #### What does this PR do?
2 |
3 | #### Which issue(s) does this PR fix?
4 |
5 | #### If this PR affects any API reference documentation, please share the updated endpoint references
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
10 | # Ignore files for PNPM, NPM and YARN
11 | pnpm-lock.yaml
12 | package-lock.json
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": true,
3 | "singleQuote": true,
4 | "trailingComma": "none",
5 | "printWidth": 100,
6 | "plugins": ["prettier-plugin-svelte"],
7 | "pluginSearchDirs": ["."],
8 | "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
9 | }
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # authorizer-svelte
2 |
3 | Svelte SDK for [authorizer.dev](https://authorizer.dev) integration in your [svelte-js](https://svelte.dev/) application. This will allow you to have authentication and authorization ready in minutes.
4 |
5 | For detailed information about all the components check [docs](https://docs.authorizer.dev/authorizer-svelte)
6 |
7 | ## Getting Started
8 |
9 | Here is a quick guide on getting started with `@authorizerdev/authorizer-svelte` package.
10 |
11 | ### Step 1 - Create Instance
12 |
13 | Get Authorizer URL by instantiating [Authorizer instance](/deployment) and configuring it with necessary [environment variables](/core/env).
14 |
15 | ### Step 2 - Install package
16 |
17 | Assuming you have svelte-js application up and running, install following package in your application
18 |
19 | ```sh
20 | npm i --save @authorizerdev/authorizer-svelte
21 | OR
22 | yarn add @authorizerdev/authorizer-svelte
23 | ```
24 |
25 | ### Step 3 - Configure Provider and use Authorizer Component
26 |
27 | Authorizer comes with global context `authorizerContext` which is available once you have configured `AuthorizerProvider` component.
28 |
29 | Configure `AuthorizerProvider` at root level in your application and import `default.css`.
30 |
31 | > Note: You can override default style with `css` variables. Check [docs](https://docs.authorizer.dev/authorizer-svelte) for more details.
32 |
33 | `eg: routes/+layout.svelte`
34 |
35 | ```svelte
36 |
40 |
41 |
48 |
49 |
50 | ```
51 |
52 | **Use `Authorizer` Component**
53 |
54 | `eg: routes/+page.svelte`
55 |
56 | ```svelte
57 |
76 |
77 | {#if state.user}
78 |
79 |
Hey 👋,
80 | {state.user.email}
81 |
82 | {#if state.loading}
83 | Processing....
84 | {:else}
85 | Logout
86 | {/if}
87 |
88 | {:else}
89 |
90 |
Welcome to Authorizer
91 |
92 |
93 |
94 | {/if}
95 | ```
96 |
97 | ## Support our work
98 |
99 | Github Sponsorship: https://github.com/sponsors/authorizerdev
100 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@authorizerdev/authorizer-svelte",
3 | "version": "0.1.9",
4 | "license": "MIT",
5 | "author": "Lakhan Samani",
6 | "scripts": {
7 | "dev": "vite dev",
8 | "build": "svelte-kit sync && svelte-package",
9 | "test": "playwright test",
10 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
11 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
12 | "lint": "prettier --plugin-search-dir . --check . && eslint .",
13 | "format": "prettier --plugin-search-dir . --write ."
14 | },
15 | "devDependencies": {
16 | "@playwright/test": "^1.25.0",
17 | "@sveltejs/adapter-auto": "next",
18 | "@sveltejs/kit": "next",
19 | "@sveltejs/package": "next",
20 | "@typescript-eslint/eslint-plugin": "^5.27.0",
21 | "@typescript-eslint/parser": "^5.27.0",
22 | "eslint": "^8.16.0",
23 | "eslint-config-prettier": "^8.3.0",
24 | "eslint-plugin-svelte3": "^4.0.0",
25 | "prettier": "^2.6.2",
26 | "prettier-plugin-svelte": "^2.7.0",
27 | "svelte": "^3.44.0",
28 | "svelte-check": "^2.7.1",
29 | "svelte-preprocess": "^4.10.6",
30 | "tslib": "^2.3.1",
31 | "typescript": "^4.7.4",
32 | "vite": "^3.1.0"
33 | },
34 | "type": "module",
35 | "dependencies": {
36 | "@authorizerdev/authorizer-js": "^1.2.6"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import type { PlaywrightTestConfig } from '@playwright/test';
2 |
3 | const config: PlaywrightTestConfig = {
4 | webServer: {
5 | command: 'npm run build && npm run preview',
6 | port: 4173
7 | }
8 | };
9 |
10 | export default config;
11 |
--------------------------------------------------------------------------------
/src/app.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | // See https://kit.svelte.dev/docs/types#app
4 | // for information about these interfaces
5 | // and what to do when importing types
6 | declare namespace App {
7 | // interface Locals {}
8 | // interface PageData {}
9 | // interface Error {}
10 | // interface Platform {}
11 | }
12 |
--------------------------------------------------------------------------------
/src/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %sveltekit.head%
8 |
9 |
10 | %sveltekit.body%
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerBasicAuthLogin.svelte:
--------------------------------------------------------------------------------
1 |
106 |
107 | {#if otpData.isScreenVisible && otpData.email}
108 |
109 | {:else}
110 |
111 | {#if componentState.error}
112 |
113 | {/if}
114 |
165 | {#if setView}
166 |
167 | setView && setView(Views.ForgotPassword)} marginBottom={'10px'}>
168 | Forgot Password?
169 |
170 | {#if state.config.is_sign_up_enabled}
171 |
172 | Don't have an account?
173 | setView && setView(Views.Signup)}>Sign Up
174 |
175 | {/if}
176 |
177 | {/if}
178 |
179 | {/if}
180 |
181 |
182 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerForgotPassword.svelte:
--------------------------------------------------------------------------------
1 |
65 |
66 | {#if componentState.successMessage}
67 |
68 | {:else}
69 | {#if componentState.error}
70 |
71 | {/if}
72 |
73 | Please enter your email address.
74 |
75 | We will send you an email to reset your password.
76 |
77 |
78 |
108 | {#if setView}
109 |
110 |
111 | Remember your password?
112 | setView && setView(Views.Login)}>Log In
113 |
114 |
115 | {/if}
116 | {/if}
117 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerMagicLinkLogin.svelte:
--------------------------------------------------------------------------------
1 |
78 |
79 | {#if componentState.successMessage}
80 |
81 | {:else}
82 | {#if componentState.error}
83 |
84 | {/if}
85 |
115 | {/if}
116 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerProvider.svelte:
--------------------------------------------------------------------------------
1 |
211 |
212 | Authorizer Provider Component
213 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerResetPassword.svelte:
--------------------------------------------------------------------------------
1 |
81 |
82 |
83 | {#if componentState.error}
84 |
85 | {/if}
86 |
143 |
144 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerRoot.svelte:
--------------------------------------------------------------------------------
1 |
58 |
59 |
60 |
61 | {#if view === Views.Login && state.config.is_basic_authentication_enabled && !state.config.is_magic_link_login_enabled}
62 |
63 | {/if}
64 | {#if view === Views.Signup && state.config.is_basic_authentication_enabled && !state.config.is_magic_link_login_enabled && state.config.is_sign_up_enabled}
65 |
66 | {/if}
67 | {#if view === Views.Login && state.config.is_magic_link_login_enabled}
68 |
69 | {/if}
70 | {#if view === Views.ForgotPassword}
71 |
72 | {/if}
73 |
74 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerSignup.svelte:
--------------------------------------------------------------------------------
1 |
127 |
128 | {#if componentState.successMessage}
129 |
130 | {:else}
131 | {#if componentState.error}
132 |
133 | {/if}
134 |
210 | {#if setView}
211 |
212 |
213 | Already have an account?
214 | setView && setView(Views.Login)}>Log In
215 |
216 |
217 | {/if}
218 | {/if}
219 |
220 |
221 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerSocialLogin.svelte:
--------------------------------------------------------------------------------
1 |
41 |
42 |
43 | {#if state.config.is_apple_login_enabled}
44 |
45 |
{
47 | if (window?.location)
48 | window.location.href = `${state.config.authorizerURL}/oauth_login/apple?${queryParams}`;
49 | }}
50 | >
51 |
52 | Sign in with Apple
53 |
54 |
55 |
56 | {/if}
57 | {#if state.config.is_google_login_enabled}
58 |
{
60 | if (window?.location)
61 | window.location.href = `${state.config.authorizerURL}/oauth_login/google?${queryParams}`;
62 | }}
63 | >
64 |
65 | Sign in with Google
66 |
67 |
68 | {/if}
69 | {#if state.config.is_github_login_enabled}
70 |
{
72 | if (window?.location)
73 | window.location.href = `${state.config.authorizerURL}/oauth_login/github?${queryParams}`;
74 | }}
75 | >
76 |
77 | Sign in with Github
78 |
79 |
80 | {/if}
81 | {#if state.config.is_facebook_login_enabled}
82 |
{
84 | if (window?.location)
85 | window.location.href = `${state.config.authorizerURL}/oauth_login/facebook?${queryParams}`;
86 | }}
87 | >
88 |
89 | Sign in with Facebook
90 |
91 |
92 | {/if}
93 | {#if state.config.is_linkedin_login_enabled}
94 |
{
96 | if (window?.location)
97 | window.location.href = `${state.config.authorizerURL}/oauth_login/linkedin?${queryParams}`;
98 | }}
99 | >
100 |
101 | Sign in with Linkedin
102 |
103 |
104 | {/if}
105 | {#if state.config.is_twitter_login_enabled}
106 |
{
108 | if (window?.location)
109 | window.location.href = `${state.config.authorizerURL}/oauth_login/twitter?${queryParams}`;
110 | }}
111 | >
112 |
113 | Sign in with Twitter
114 |
115 |
116 | {/if}
117 | {#if state.config.is_microsoft_login_enabled}
118 |
{
120 | if (window?.location)
121 | window.location.href = `${state.config.authorizerURL}/oauth_login/microsoft?${queryParams}`;
122 | }}
123 | >
124 |
125 | Sign in with Microsoft
126 |
127 |
128 | {/if}
129 | {#if hasSocialLogin && (state.config.is_basic_authentication_enabled || state.config.is_magic_link_login_enabled)}
130 |
OR
131 | {/if}
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/src/lib/components/AuthorizerVerifyOtp.svelte:
--------------------------------------------------------------------------------
1 |
108 |
109 | {#if componentState.successMessage}
110 |
115 | {/if}
116 | {#if componentState.error}
117 |
118 | {/if}
119 |
120 | Please enter the OTP you received on your email address.
121 |
122 |
123 |
150 | {#if setView}
151 |
152 | {#if componentState.sendingOtp}
153 | Sending ...
154 | {:else}
155 | Resend OTP
156 | {/if}
157 | {#if state.config.is_sign_up_enabled}
158 |
159 | Don't have an account?
160 | setView && setView(Views.Signup)}>Sign Up
161 |
162 | {/if}
163 |
164 | {/if}
165 |
--------------------------------------------------------------------------------
/src/lib/components/Message.svelte:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 | {capitalizeFirstLetter(text)}
15 | {#if onClose}
16 | onClose && onClose()}>
17 |
18 |
19 | {/if}
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/lib/components/PasswordStrengthIndicator.svelte:
--------------------------------------------------------------------------------
1 |
44 |
45 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/src/lib/constants/index.ts:
--------------------------------------------------------------------------------
1 | export enum Views {
2 | Login,
3 | Signup,
4 | ForgotPassword
5 | }
6 |
7 | export enum ButtonAppearance {
8 | Primary,
9 | Default
10 | }
11 |
12 | export enum MessageType {
13 | Error,
14 | Success
15 | }
16 |
17 | export enum AuthorizerProviderActionType {
18 | SET_USER = 'SET_USER',
19 | SET_TOKEN = 'SET_TOKEN',
20 | SET_LOADING = 'SET_LOADING',
21 | SET_AUTH_DATA = 'SET_AUTH_DATA',
22 | SET_CONFIG = 'SET_CONFIG'
23 | }
24 |
25 | // TODO use based on theme primary color
26 | export const passwordStrengthIndicatorOpacity: Record = {
27 | default: 0.15,
28 | weak: 0.4,
29 | good: 0.6,
30 | strong: 0.8,
31 | veryStrong: 1
32 | };
33 |
--------------------------------------------------------------------------------
/src/lib/icons/Apple.svelte:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/lib/icons/Close.svelte:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/lib/icons/Facebook.svelte:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/src/lib/icons/Github.svelte:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/lib/icons/Google.svelte:
--------------------------------------------------------------------------------
1 |
2 |
22 |
23 |
--------------------------------------------------------------------------------
/src/lib/icons/Linkedin.svelte:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/src/lib/icons/Microsoft.svelte:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/src/lib/icons/Twitter.svelte:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/lib/icons/index.ts:
--------------------------------------------------------------------------------
1 | import Apple from './Apple.svelte';
2 | import Close from './Close.svelte';
3 | import Facebook from './Facebook.svelte';
4 | import Github from './Github.svelte';
5 | import Google from './Google.svelte';
6 | import Linkedin from './Linkedin.svelte';
7 | import Twitter from './Twitter.svelte';
8 | import Microsoft from './Microsoft.svelte';
9 |
10 | export { Apple, Facebook, Github, Google, Linkedin, Twitter, Close, Microsoft };
11 |
--------------------------------------------------------------------------------
/src/lib/index.ts:
--------------------------------------------------------------------------------
1 | // Reexport your entry components here
2 | import AuthorizerProvider from './components/AuthorizerProvider.svelte';
3 | import AuthorizerSignup from './components/AuthorizerSignup.svelte';
4 | import AuthorizerBasicAuthLogin from './components/AuthorizerBasicAuthLogin.svelte';
5 | import AuthorizerMagicLinkLogin from './components/AuthorizerMagicLinkLogin.svelte';
6 | import AuthorizerForgotPassword from './components/AuthorizerForgotPassword.svelte';
7 | import AuthorizerSocialLogin from './components/AuthorizerSocialLogin.svelte';
8 | import AuthorizerResetPassword from './components/AuthorizerResetPassword.svelte';
9 | import AuthorizerVerifyOtp from './components/AuthorizerVerifyOtp.svelte';
10 | import AuthorizerRoot from './components/AuthorizerRoot.svelte';
11 |
12 | export {
13 | AuthorizerProvider,
14 | AuthorizerSignup,
15 | AuthorizerBasicAuthLogin,
16 | AuthorizerMagicLinkLogin,
17 | AuthorizerForgotPassword,
18 | AuthorizerSocialLogin,
19 | AuthorizerResetPassword,
20 | AuthorizerVerifyOtp,
21 | AuthorizerRoot as Authorizer
22 | };
23 |
--------------------------------------------------------------------------------
/src/lib/store/index.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-empty-function */
2 | import { writable } from 'svelte/store';
3 | import { Authorizer } from '@authorizerdev/authorizer-js';
4 | import { hasWindow } from '../utils/window';
5 | import type { AuthorizerState } from '$lib/types';
6 |
7 | export const store = writable({
8 | config: {
9 | authorizerURL: '',
10 | redirectURL: '/',
11 | client_id: '',
12 | is_google_login_enabled: false,
13 | is_github_login_enabled: false,
14 | is_facebook_login_enabled: false,
15 | is_linkedin_login_enabled: false,
16 | is_apple_login_enabled: false,
17 | is_twitter_login_enabled: false,
18 | is_microsoft_login_enabled: false,
19 | is_email_verification_enabled: false,
20 | is_basic_authentication_enabled: false,
21 | is_magic_link_login_enabled: false,
22 | is_sign_up_enabled: false,
23 | is_strong_password_enabled: true
24 | },
25 | user: null,
26 | token: null,
27 | loading: false,
28 | setLoading: () => {},
29 | setToken: () => {},
30 | setUser: () => {},
31 | setAuthData: () => {},
32 | authorizerRef: new Authorizer({
33 | authorizerURL: `http://localhost:8080`,
34 | redirectURL: hasWindow() ? window.location.origin : '/',
35 | clientID: ''
36 | }),
37 | logout: async () => {}
38 | });
39 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledButton.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
28 |
29 |
48 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledFlex.svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
17 |
18 |
19 |
20 |
25 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledFooter.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
14 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledFormGroup.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 | {#if hasError}
9 |
10 | {/if}
11 |
12 |
13 |
54 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledLink.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledMessageWrapper.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
14 |
15 |
16 |
25 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledPasswordStrength.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
13 |
14 |
24 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledPasswordStrengthWrapper.svelte:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledSeparator.svelte:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
29 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/StyledWrapper.svelte:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
--------------------------------------------------------------------------------
/src/lib/styledComponents/index.ts:
--------------------------------------------------------------------------------
1 | import StyledWrapper from './StyledWrapper.svelte';
2 | import StyledButton from './StyledButton.svelte';
3 | import StyledLink from './StyledLink.svelte';
4 | import StyledSeparator from './StyledSeparator.svelte';
5 | import StyledFooter from './StyledFooter.svelte';
6 | import StyledMessageWrapper from './StyledMessageWrapper.svelte';
7 | import StyledFlex from './StyledFlex.svelte';
8 | import StyledFormGroup from './StyledFormGroup.svelte';
9 | import StyledPasswordStrength from './StyledPasswordStrength.svelte';
10 | import StyledPasswordStrengthWrapper from './StyledPasswordStrengthWrapper.svelte';
11 |
12 | export {
13 | StyledWrapper,
14 | StyledButton,
15 | StyledLink,
16 | StyledSeparator,
17 | StyledFooter,
18 | StyledMessageWrapper,
19 | StyledFlex,
20 | StyledFormGroup,
21 | StyledPasswordStrength,
22 | StyledPasswordStrengthWrapper
23 | };
24 |
--------------------------------------------------------------------------------
/src/lib/styles/default.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --authorizer-primary-color: #3b82f6;
3 | --authorizer-primary-disabled-color: #60a5fa;
4 | --authorizer-gray-color: #d1d5db;
5 | --authorizer-white-color: #ffffff;
6 | --authorizer-danger-color: #dc2626;
7 | --authorizer-success-color: #10b981;
8 | --authorizer-text-color: #374151;
9 | --authorizer-fonts-font-stack: -apple-system, system-ui, sans-serif;
10 | --authorizer-fonts-large-text: 18px;
11 | --authorizer-fonts-medium-text: 14px;
12 | --authorizer-fonts-small-text: 12px;
13 | --authorizer-fonts-tiny-text: 10px;
14 | --authorizer-radius-card: 5px;
15 | --authorizer-radius-button: 5px;
16 | --authorizer-radius-input: 5px;
17 | }
18 |
--------------------------------------------------------------------------------
/src/lib/types/index.ts:
--------------------------------------------------------------------------------
1 | import type { AuthToken, User, Authorizer } from '@authorizerdev/authorizer-js';
2 | import type { AuthorizerProviderActionType } from '../constants';
3 |
4 | export type ConfigState = {
5 | authorizerURL?: string;
6 | redirectURL?: string;
7 | client_id?: string;
8 | is_google_login_enabled?: boolean;
9 | is_github_login_enabled?: boolean;
10 | is_facebook_login_enabled?: boolean;
11 | is_linkedin_login_enabled?: boolean;
12 | is_apple_login_enabled?: boolean;
13 | is_twitter_login_enabled?: boolean;
14 | is_microsoft_login_enabled?: boolean;
15 | is_email_verification_enabled?: boolean;
16 | is_basic_authentication_enabled?: boolean;
17 | is_magic_link_login_enabled?: boolean;
18 | is_sign_up_enabled?: boolean;
19 | is_strong_password_enabled?: boolean;
20 | };
21 |
22 | export type AuthorizerProviderAction = {
23 | type: AuthorizerProviderActionType;
24 | payload: any;
25 | };
26 |
27 | export type AuthorizerInputState = {
28 | user: User | null;
29 | token: AuthToken | null;
30 | loading: boolean;
31 | config: ConfigState;
32 | };
33 |
34 | export type AuthorizerState = {
35 | user: User | null;
36 | token: AuthToken | null;
37 | loading: boolean;
38 | config: ConfigState;
39 | logout: () => Promise;
40 | setLoading: (data: boolean) => void;
41 | setUser: (data: null | User) => void;
42 | setToken: (data: null | AuthToken) => void;
43 | setAuthData: (data: AuthorizerInputState) => void;
44 | authorizerRef: Authorizer;
45 | };
46 |
47 | export type OtpDataType = {
48 | isScreenVisible: boolean;
49 | email: string;
50 | };
51 |
--------------------------------------------------------------------------------
/src/lib/utils/common.ts:
--------------------------------------------------------------------------------
1 | import { hasWindow } from './window';
2 |
3 | export const getIntervalDiff = (accessTokenExpiresAt: number): number => {
4 | const expiresAt = accessTokenExpiresAt * 1000 - 300000;
5 | const currentDate = new Date();
6 |
7 | const millisecond = new Date(expiresAt).getTime() - currentDate.getTime();
8 | return millisecond;
9 | };
10 |
11 | export const getCrypto = () => {
12 | //ie 11.x uses msCrypto
13 | return hasWindow() ? window.crypto : null;
14 | };
15 |
16 | export const createRandomString = (): string => {
17 | const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.';
18 | let random = '';
19 | const crypto = getCrypto();
20 | if (crypto) {
21 | const randomValues = Array.from(crypto.getRandomValues(new Uint8Array(43)));
22 | randomValues.forEach((v) => (random += charset[v % charset.length]));
23 | }
24 | return random;
25 | };
26 |
27 | export const createQueryParams = (params: Record): string => {
28 | return Object.keys(params)
29 | .filter((k) => typeof params[k] !== 'undefined')
30 | .map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
31 | .join('&');
32 | };
33 |
34 | export const isValidEmail = (email: string): boolean => {
35 | const regex =
36 | /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
37 | const lowerCaseEmail = (email || ``).trim().toLocaleLowerCase();
38 | return regex.test(lowerCaseEmail);
39 | };
40 |
41 | export const capitalizeFirstLetter = (data: string): string => {
42 | if (!data) return '';
43 | return data ? data.charAt(0).toUpperCase() + data.slice(1) : ``;
44 | };
45 |
46 | export const isValidOtp = (otp: string): boolean => {
47 | const re = /^([A-Z0-9]{6})$/;
48 | const trimmedOTP = (otp || ``).trim();
49 | return re.test(trimmedOTP);
50 | };
51 |
52 | export const formatErrorMessage = (message: string): string => {
53 | return message.replace(`[GraphQL] `, '');
54 | };
55 |
56 | export const hasSpecialChar = (char: string): boolean => {
57 | const re = /[`!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?~]/;
58 | return re.test(char);
59 | };
60 |
61 | export const validatePassword = (
62 | value: string
63 | ): {
64 | score: number;
65 | strength: string;
66 | hasSixChar: boolean;
67 | hasLowerCase: boolean;
68 | hasUpperCase: boolean;
69 | hasNumericChar: boolean;
70 | hasSpecialChar: boolean;
71 | maxThirtySixChar: boolean;
72 | isValid: boolean;
73 | } => {
74 | const res = {
75 | score: 0,
76 | strength: '',
77 | hasSixChar: false,
78 | hasLowerCase: false,
79 | hasUpperCase: false,
80 | hasNumericChar: false,
81 | hasSpecialChar: false,
82 | maxThirtySixChar: false
83 | };
84 |
85 | if (value.length >= 6) {
86 | res.score = res.score + 1;
87 | res.hasSixChar = true;
88 | }
89 |
90 | if (value.length > 0 && value.length <= 36) {
91 | res.score = res.score + 1;
92 | res.maxThirtySixChar = true;
93 | }
94 |
95 | Array.from(value).forEach((char: any) => {
96 | if (char >= 'A' && char <= 'Z' && !res.hasUpperCase) {
97 | res.score = res.score + 1;
98 | res.hasUpperCase = true;
99 | } else if (char >= 'a' && char <= 'z' && !res.hasLowerCase) {
100 | res.score = res.score + 1;
101 | res.hasLowerCase = true;
102 | } else if (char >= '0' && char <= '9' && !res.hasNumericChar) {
103 | res.score = res.score + 1;
104 | res.hasNumericChar = true;
105 | } else if (hasSpecialChar(char) && !res.hasSpecialChar) {
106 | res.score = res.score + 1;
107 | res.hasSpecialChar = true;
108 | }
109 | });
110 |
111 | if (res.score <= 2) {
112 | res.strength = 'Weak';
113 | } else if (res.score <= 4) {
114 | res.strength = 'Good';
115 | } else if (res.score <= 5) {
116 | res.strength = 'Strong';
117 | } else {
118 | res.strength = 'Very Strong';
119 | }
120 |
121 | const isValid = Object.values(res).every((i) => Boolean(i));
122 | return { ...res, isValid };
123 | };
124 |
--------------------------------------------------------------------------------
/src/lib/utils/url.ts:
--------------------------------------------------------------------------------
1 | import { hasWindow } from './window';
2 |
3 | export const getSearchParams = (search = '') => {
4 | let searchPrams = search;
5 | if (!searchPrams && hasWindow()) {
6 | searchPrams = window.location.search;
7 | }
8 | const urlSearchParams = new URLSearchParams(`${searchPrams}`);
9 | const params = Object.fromEntries(urlSearchParams.entries());
10 | return params;
11 | };
12 |
--------------------------------------------------------------------------------
/src/lib/utils/window.ts:
--------------------------------------------------------------------------------
1 | export const hasWindow = (): boolean => typeof window !== 'undefined';
2 |
--------------------------------------------------------------------------------
/src/routes/+layout.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
17 |
18 |
19 |
43 |
--------------------------------------------------------------------------------
/src/routes/+page.svelte:
--------------------------------------------------------------------------------
1 |
20 |
21 | {#if state.token}
22 |
23 |
Hey 👋,
24 |
Thank you for joining Authorizer demo app.
25 |
26 | Your email address is
27 |
28 | {state.user?.email}
29 |
30 |
31 |
32 | {#if state.loading}
33 |
Processing....
34 | {:else}
35 |
Logout
36 | {/if}
37 |
38 | {:else}
39 |
40 |
Welcome to Authorizer
41 |
42 |
43 |
44 | {/if}
45 |
46 |
54 |
--------------------------------------------------------------------------------
/src/routes/reset-password/+page.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 | Reset Password
6 |
7 |
8 |
--------------------------------------------------------------------------------
/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/authorizerdev/authorizer-svelte/a558bf9848c0536a3d4b4e54cb2ed7fbcf647e95/static/favicon.png
--------------------------------------------------------------------------------
/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-auto';
2 | import preprocess from 'svelte-preprocess';
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | // Consult https://github.com/sveltejs/svelte-preprocess
7 | // for more information about preprocessors
8 | preprocess: preprocess(),
9 |
10 | kit: {
11 | adapter: adapter()
12 | }
13 | };
14 |
15 | export default config;
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "allowJs": true,
5 | "checkJs": true,
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "resolveJsonModule": true,
9 | "skipLibCheck": true,
10 | "sourceMap": true,
11 | "strict": true
12 | }
13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
14 | //
15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
16 | // from the referenced tsconfig.json - TypeScript does not merge them in
17 | }
18 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { sveltekit } from '@sveltejs/kit/vite';
2 | import type { UserConfig } from 'vite';
3 |
4 | const config: UserConfig = {
5 | plugins: [sveltekit()]
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------