Compare commits
11 Commits
0.1.0-beta
...
0.1.0-beta
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b1dd6f2c3b | ||
![]() |
f5ea94f63c | ||
![]() |
653befc737 | ||
![]() |
6fed439ec2 | ||
![]() |
5bd6fa5bc9 | ||
![]() |
75709e9f48 | ||
![]() |
b1b7f47f4c | ||
![]() |
e429a1f860 | ||
![]() |
6819597a79 | ||
![]() |
b34b385be5 | ||
![]() |
5acf59d16e |
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
@@ -41,12 +41,12 @@ jobs:
|
|||||||
make clean && \
|
make clean && \
|
||||||
CGO_ENABLED=1 GOOS=windows CC=/usr/bin/x86_64-w64-mingw32-gcc make && \
|
CGO_ENABLED=1 GOOS=windows CC=/usr/bin/x86_64-w64-mingw32-gcc make && \
|
||||||
mv build/server build/server.exe && \
|
mv build/server build/server.exe && \
|
||||||
zip -vr authorizer-${VERSION}-windows-amd64.zip .env app build templates
|
zip -vr authorizer-${VERSION}-windows-amd64.zip .env app/build build templates
|
||||||
- name: Package files for linux
|
- name: Package files for linux
|
||||||
run: |
|
run: |
|
||||||
make clean && \
|
make clean && \
|
||||||
CGO_ENABLED=1 make && \
|
CGO_ENABLED=1 make && \
|
||||||
tar cvfz authorizer-${VERSION}-linux-amd64.tar.gz .env app build templates
|
tar cvfz authorizer-${VERSION}-linux-amd64.tar.gz .env app/build build templates
|
||||||
- name: Upload assets
|
- name: Upload assets
|
||||||
run: |
|
run: |
|
||||||
github-assets-uploader -f authorizer-${VERSION}-windows-amd64.zip -mediatype application/zip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION} && \
|
github-assets-uploader -f authorizer-${VERSION}-windows-amd64.zip -mediatype application/zip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION} && \
|
||||||
|
6
TODO.md
6
TODO.md
@@ -14,3 +14,9 @@ For the first version we will only support setting roles master list via env
|
|||||||
- [x] Return roles in users list for super admin
|
- [x] Return roles in users list for super admin
|
||||||
- [x] Add roles to the JWT token generation
|
- [x] Add roles to the JWT token generation
|
||||||
- [x] Validate token should also validate the role, if roles to validate again is present in request
|
- [x] Validate token should also validate the role, if roles to validate again is present in request
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
|
||||||
|
- [x] Fix email template
|
||||||
|
- [x] Add support for organization name in .env
|
||||||
|
- [x] Add support for organization logo in .env
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
30
app/package-lock.json
generated
30
app/package-lock.json
generated
@@ -8,7 +8,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-react": "^0.1.0-beta.16",
|
"@authorizerdev/authorizer-react": "^0.1.0-beta.18",
|
||||||
"@types/react": "^17.0.15",
|
"@types/react": "^17.0.15",
|
||||||
"@types/react-dom": "^17.0.9",
|
"@types/react-dom": "^17.0.9",
|
||||||
"esbuild": "^0.12.17",
|
"esbuild": "^0.12.17",
|
||||||
@@ -22,9 +22,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@authorizerdev/authorizer-js": {
|
"node_modules/@authorizerdev/authorizer-js": {
|
||||||
"version": "0.1.0-beta.16",
|
"version": "0.1.0-beta.19",
|
||||||
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-0.1.0-beta.16.tgz",
|
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-0.1.0-beta.19.tgz",
|
||||||
"integrity": "sha512-RyjWhVbLYvmkcAT+2ddpRhrt7P5DBVKtGKjHWRugSqenTW7XFQMlhQqx5Z09DeqLw3Lsq0VVZ5h8tWcExHvwEw==",
|
"integrity": "sha512-//uYjklwQfQKqLJHMAyjdrzh2nz6DycB3lEgl6bTXxmSbrz+l1kQyxB3y8wP/W30IrBQz8bZb+1sau+LD/FU7g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-fetch": "^2.6.1"
|
"node-fetch": "^2.6.1"
|
||||||
},
|
},
|
||||||
@@ -33,11 +33,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@authorizerdev/authorizer-react": {
|
"node_modules/@authorizerdev/authorizer-react": {
|
||||||
"version": "0.1.0-beta.16",
|
"version": "0.1.0-beta.18",
|
||||||
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-0.1.0-beta.16.tgz",
|
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-0.1.0-beta.18.tgz",
|
||||||
"integrity": "sha512-b00LH0gtfMh/opFaGDF+EkxDOpNkCj/TNVjyW2wbiOFdC4HgLhc+UbPgL5/rDDol4XQsToL3SmwxmSxB2lWWuQ==",
|
"integrity": "sha512-lRWWlS9akZwwINRW1NatsbMob06NXht3HXNTUTlu1s8m1YjxmFRE/AL6UIplzAYTpR6eDWMxEEaS0qAVxovUcg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-js": "^0.1.0-beta.16",
|
"@authorizerdev/authorizer-js": "^0.1.0-beta.19",
|
||||||
"final-form": "^4.20.2",
|
"final-form": "^4.20.2",
|
||||||
"react-final-form": "^6.5.3",
|
"react-final-form": "^6.5.3",
|
||||||
"styled-components": "^5.3.0"
|
"styled-components": "^5.3.0"
|
||||||
@@ -797,19 +797,19 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-js": {
|
"@authorizerdev/authorizer-js": {
|
||||||
"version": "0.1.0-beta.16",
|
"version": "0.1.0-beta.19",
|
||||||
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-0.1.0-beta.16.tgz",
|
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-0.1.0-beta.19.tgz",
|
||||||
"integrity": "sha512-RyjWhVbLYvmkcAT+2ddpRhrt7P5DBVKtGKjHWRugSqenTW7XFQMlhQqx5Z09DeqLw3Lsq0VVZ5h8tWcExHvwEw==",
|
"integrity": "sha512-//uYjklwQfQKqLJHMAyjdrzh2nz6DycB3lEgl6bTXxmSbrz+l1kQyxB3y8wP/W30IrBQz8bZb+1sau+LD/FU7g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"node-fetch": "^2.6.1"
|
"node-fetch": "^2.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@authorizerdev/authorizer-react": {
|
"@authorizerdev/authorizer-react": {
|
||||||
"version": "0.1.0-beta.16",
|
"version": "0.1.0-beta.18",
|
||||||
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-0.1.0-beta.16.tgz",
|
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-0.1.0-beta.18.tgz",
|
||||||
"integrity": "sha512-b00LH0gtfMh/opFaGDF+EkxDOpNkCj/TNVjyW2wbiOFdC4HgLhc+UbPgL5/rDDol4XQsToL3SmwxmSxB2lWWuQ==",
|
"integrity": "sha512-lRWWlS9akZwwINRW1NatsbMob06NXht3HXNTUTlu1s8m1YjxmFRE/AL6UIplzAYTpR6eDWMxEEaS0qAVxovUcg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@authorizerdev/authorizer-js": "^0.1.0-beta.16",
|
"@authorizerdev/authorizer-js": "^0.1.0-beta.19",
|
||||||
"final-form": "^4.20.2",
|
"final-form": "^4.20.2",
|
||||||
"react-final-form": "^6.5.3",
|
"react-final-form": "^6.5.3",
|
||||||
"styled-components": "^5.3.0"
|
"styled-components": "^5.3.0"
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
"author": "Lakhan Samani",
|
"author": "Lakhan Samani",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-react": "^0.1.0-beta.16",
|
"@authorizerdev/authorizer-react": "^0.1.0-beta.18",
|
||||||
"@types/react": "^17.0.15",
|
"@types/react": "^17.0.15",
|
||||||
"@types/react-dom": "^17.0.9",
|
"@types/react-dom": "^17.0.9",
|
||||||
"esbuild": "^0.12.17",
|
"esbuild": "^0.12.17",
|
||||||
|
@@ -4,30 +4,52 @@ import { AuthorizerProvider } from '@authorizerdev/authorizer-react';
|
|||||||
import Root from './Root';
|
import Root from './Root';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const globalState: Record<string, string> = window['__authorizer__'];
|
const globalState: Record<string, string> = window['__authorizer__'];
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
<div
|
||||||
<div
|
style={{
|
||||||
style={{
|
display: 'flex',
|
||||||
width: 400,
|
justifyContent: 'center',
|
||||||
margin: `10px auto`,
|
flexDirection: 'column',
|
||||||
border: `1px solid #D1D5DB`,
|
}}
|
||||||
padding: `25px 20px`,
|
>
|
||||||
borderRadius: 5,
|
<div
|
||||||
}}
|
style={{
|
||||||
>
|
display: 'flex',
|
||||||
<BrowserRouter>
|
justifyContent: 'center',
|
||||||
<AuthorizerProvider
|
marginTop: 20,
|
||||||
config={{
|
flexDirection: 'column',
|
||||||
authorizerURL: globalState.authorizerURL,
|
alignItems: 'center',
|
||||||
redirectURL: globalState.redirectURL,
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<img
|
||||||
<Root />
|
src={`${globalState.organizationLogo}`}
|
||||||
</AuthorizerProvider>
|
alt="logo"
|
||||||
</BrowserRouter>
|
style={{ height: 60, width: 60, objectFit: 'cover' }}
|
||||||
</div>
|
/>
|
||||||
</div>
|
<h1>{globalState.organizationName}</h1>
|
||||||
);
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: 400,
|
||||||
|
margin: `10px auto`,
|
||||||
|
border: `1px solid #D1D5DB`,
|
||||||
|
padding: `25px 20px`,
|
||||||
|
borderRadius: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BrowserRouter>
|
||||||
|
<AuthorizerProvider
|
||||||
|
config={{
|
||||||
|
authorizerURL: globalState.authorizerURL,
|
||||||
|
redirectURL: globalState.redirectURL,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Root />
|
||||||
|
</AuthorizerProvider>
|
||||||
|
</BrowserRouter>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@@ -10,9 +10,9 @@ export default function Root() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (token) {
|
if (token) {
|
||||||
const url = new URL(config.redirectURL);
|
const url = new URL(config.redirectURL || '/app');
|
||||||
if (url.origin !== window.location.origin) {
|
if (url.origin !== window.location.origin) {
|
||||||
window.location.href = config.redirectURL;
|
window.location.href = config.redirectURL || '/app';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return () => {};
|
return () => {};
|
||||||
|
@@ -2,9 +2,9 @@ import React, { Fragment } from 'react';
|
|||||||
import { Authorizer } from '@authorizerdev/authorizer-react';
|
import { Authorizer } from '@authorizerdev/authorizer-react';
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Authorizer />
|
<Authorizer />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
VERSION="$1"
|
VERSION="$1"
|
||||||
make clean && CGO_ENABLED=1 VERSION=${VERSION} make
|
make clean && CGO_ENABLED=1 VERSION=${VERSION} make
|
||||||
FILE_NAME=authorizer-${VERSION}-darwin-amd64.tar.gz
|
FILE_NAME=authorizer-${VERSION}-darwin-amd64.tar.gz
|
||||||
tar cvfz ${FILE_NAME} .env app build templates
|
tar cvfz ${FILE_NAME} .env app/build build templates
|
||||||
AUTH="Authorization: token $GITHUB_TOKEN"
|
AUTH="Authorization: token $GITHUB_TOKEN"
|
||||||
RELASE_INFO=$(curl -sH "$AUTH" https://api.github.com/repos/authorizerdev/authorizer/releases/tags/${VERSION})
|
RELASE_INFO=$(curl -sH "$AUTH" https://api.github.com/repos/authorizerdev/authorizer/releases/tags/${VERSION})
|
||||||
echo $RELASE_INFO
|
echo $RELASE_INFO
|
||||||
|
@@ -37,4 +37,8 @@ var (
|
|||||||
FACEBOOK_CLIENT_SECRET = ""
|
FACEBOOK_CLIENT_SECRET = ""
|
||||||
TWITTER_CLIENT_ID = ""
|
TWITTER_CLIENT_ID = ""
|
||||||
TWITTER_CLIENT_SECRET = ""
|
TWITTER_CLIENT_SECRET = ""
|
||||||
|
|
||||||
|
// Org envs
|
||||||
|
ORGANIZATION_NAME = "Authorizer"
|
||||||
|
ORGANIZATION_LOGO = "https://authorizer.dev/images/logo.png"
|
||||||
)
|
)
|
||||||
|
@@ -23,8 +23,7 @@ func (r *Role) BeforeCreate(tx *gorm.DB) (err error) {
|
|||||||
func (mgr *manager) SaveRoles(roles []Role) error {
|
func (mgr *manager) SaveRoles(roles []Role) error {
|
||||||
res := mgr.db.Clauses(
|
res := mgr.db.Clauses(
|
||||||
clause.OnConflict{
|
clause.OnConflict{
|
||||||
OnConstraint: "authorizer_roles_role_key",
|
DoNothing: true,
|
||||||
DoNothing: true,
|
|
||||||
}).Create(&roles)
|
}).Create(&roles)
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
log.Println(`Error saving roles`)
|
log.Println(`Error saving roles`)
|
||||||
|
@@ -174,4 +174,12 @@ func InitEnv() {
|
|||||||
if constants.JWT_ROLE_CLAIM == "" {
|
if constants.JWT_ROLE_CLAIM == "" {
|
||||||
constants.JWT_ROLE_CLAIM = "role"
|
constants.JWT_ROLE_CLAIM = "role"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if os.Getenv("ORGANIZATION_NAME") != "" {
|
||||||
|
constants.ORGANIZATION_NAME = os.Getenv("ORGANIZATION_NAME")
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("ORGANIZATION_LOGO") != "" {
|
||||||
|
constants.ORGANIZATION_LOGO = os.Getenv("ORGANIZATION_LOGO")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,8 +75,10 @@ func AppHandler() gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
c.HTML(http.StatusOK, "app.tmpl", gin.H{
|
c.HTML(http.StatusOK, "app.tmpl", gin.H{
|
||||||
"data": map[string]string{
|
"data": map[string]string{
|
||||||
"authorizerURL": stateObj.AuthorizerURL,
|
"authorizerURL": stateObj.AuthorizerURL,
|
||||||
"redirectURL": stateObj.RedirectURL,
|
"redirectURL": stateObj.RedirectURL,
|
||||||
|
"organizationName": constants.ORGANIZATION_NAME,
|
||||||
|
"organizationLogo": constants.ORGANIZATION_LOGO,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,6 @@ func AdminUpdateUser(ctx context.Context, params model.AdminUpdateUserInput) (*m
|
|||||||
}
|
}
|
||||||
|
|
||||||
user, err := db.Mgr.GetUserByID(params.ID)
|
user, err := db.Mgr.GetUserByID(params.ID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, fmt.Errorf(`User not found`)
|
return res, fmt.Errorf(`User not found`)
|
||||||
}
|
}
|
||||||
@@ -114,9 +113,8 @@ func AdminUpdateUser(ctx context.Context, params model.AdminUpdateUserInput) (*m
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
userIdStr := fmt.Sprintf("%v", user.ID)
|
|
||||||
res = &model.User{
|
res = &model.User{
|
||||||
ID: userIdStr,
|
ID: params.ID,
|
||||||
Email: user.Email,
|
Email: user.Email,
|
||||||
Image: &user.Image,
|
Image: &user.Image,
|
||||||
FirstName: &user.FirstName,
|
FirstName: &user.FirstName,
|
||||||
|
@@ -36,8 +36,8 @@ func Token(ctx context.Context, role *string) (*model.AuthResponse, error) {
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if role != nil && role != &claimRole {
|
if role != nil && *role != claimRole {
|
||||||
return res, fmt.Errorf(`unauthorized. invalid role for a given token`)
|
return res, fmt.Errorf(`unauthorized`)
|
||||||
}
|
}
|
||||||
|
|
||||||
userIdStr := fmt.Sprintf("%v", user.ID)
|
userIdStr := fmt.Sprintf("%v", user.ID)
|
||||||
|
@@ -16,17 +16,91 @@ func SendVerificationMail(toEmail, token string) error {
|
|||||||
|
|
||||||
Subject := "Please verify your email"
|
Subject := "Please verify your email"
|
||||||
message := fmt.Sprintf(`
|
message := fmt.Sprintf(`
|
||||||
<!DOCTYPE HTML PULBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html>
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||||
<head>
|
|
||||||
<meta http-equiv="content-type" content="text/html"; charset=ISO-8859-1">
|
<head>
|
||||||
</head>
|
<meta charset="UTF-8">
|
||||||
<body>
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||||
<h1>Please verify your email by clicking on the link below </h1><br/>
|
<meta name="x-apple-disable-message-reformatting">
|
||||||
<a href="%s">Click here to verify</a>
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
</body>
|
<meta content="telephone=no" name="format-detection">
|
||||||
</html>
|
<title></title>
|
||||||
`, constants.AUTHORIZER_URL+"/verify_email"+"?token="+token)
|
<!--[if (mso 16)]>
|
||||||
|
<style type="text/css">
|
||||||
|
a {}
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
<!--[if gte mso 9]><style>sup { font-size: 100%% !important; }</style><![endif]-->
|
||||||
|
<!--[if gte mso 9]>
|
||||||
|
<xml>
|
||||||
|
<o:OfficeDocumentSettings>
|
||||||
|
<o:AllowPNG></o:AllowPNG>
|
||||||
|
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||||
|
</o:OfficeDocumentSettings>
|
||||||
|
</xml>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="font-family: sans-serif;">
|
||||||
|
<div class="es-wrapper-color">
|
||||||
|
<!--[if gte mso 9]>
|
||||||
|
<v:background xmlns:v="urn:schemas-microsoft-com:vml" fill="t">
|
||||||
|
<v:fill type="tile" color="#ffffff"></v:fill>
|
||||||
|
</v:background>
|
||||||
|
<![endif]-->
|
||||||
|
<table class="es-wrapper" width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-email-paddings" valign="top">
|
||||||
|
<table class="es-content esd-footer-popover" cellspacing="0" cellpadding="0" align="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-stripe" align="center">
|
||||||
|
<table class="es-content-body" style="border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;border-bottom:1px solid transparent;padding:20px 0px;" width="600" cellspacing="0" cellpadding="0" bgcolor="#ffffff" align="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-structure es-p20t es-p40b es-p40r es-p40l" esd-custom-block-id="8537" align="left">
|
||||||
|
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-container-frame" width="518" align="left">
|
||||||
|
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-block-image es-m-txt-c es-p5b" style="font-size:0;padding:10px" align="center"><a target="_blank"><img src="%s" alt="icon" style="display: block;" title="icon" width="30"></a></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr style="background: rgb(249,250,251);padding: 10px;margin-bottom:10px;border-radius:5px;">
|
||||||
|
<td class="esd-block-text es-m-txt-c es-p15t" align="center" style="padding:10px;padding-bottom:30px;">
|
||||||
|
<p>Hey there 👋</p>
|
||||||
|
<p>We received a request to sign-up for <b>%s</b>. If this is correct, please confirm your email address by clicking the button below.</p> <br/>
|
||||||
|
<a href="%s" class="es-button" target="_blank" style="text-decoration: none;padding:10px 15px;background-color: rgba(59,130,246,1);color: #fff;font-size: 1em;border-radius:5px;">Confirm Email</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="position: absolute; left: -9999px; top: -9999px; margin: 0px;"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`, constants.ORGANIZATION_LOGO, constants.ORGANIZATION_NAME, constants.AUTHORIZER_URL+"/verify_email"+"?token="+token)
|
||||||
bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
|
bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
|
||||||
|
|
||||||
return sender.SendMail(Receiver, Subject, bodyMessage)
|
return sender.SendMail(Receiver, Subject, bodyMessage)
|
||||||
@@ -46,17 +120,92 @@ func SendForgotPasswordMail(toEmail, token, host string) error {
|
|||||||
Subject := "Reset Password"
|
Subject := "Reset Password"
|
||||||
|
|
||||||
message := fmt.Sprintf(`
|
message := fmt.Sprintf(`
|
||||||
<!DOCTYPE HTML PULBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html>
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||||
<head>
|
|
||||||
<meta http-equiv="content-type" content="text/html"; charset=ISO-8859-1">
|
<head>
|
||||||
</head>
|
<meta charset="UTF-8">
|
||||||
<body>
|
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||||
<h1>Please use the link below to reset password </h1><br/>
|
<meta name="x-apple-disable-message-reformatting">
|
||||||
<a href="%s">Reset Password</a>
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
</body>
|
<meta content="telephone=no" name="format-detection">
|
||||||
</html>
|
<title></title>
|
||||||
`, constants.RESET_PASSWORD_URL+"?token="+token)
|
<!--[if (mso 16)]>
|
||||||
|
<style type="text/css">
|
||||||
|
a {}
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
<!--[if gte mso 9]><style>sup { font-size: 100%% !important; }</style><![endif]-->
|
||||||
|
<!--[if gte mso 9]>
|
||||||
|
<xml>
|
||||||
|
<o:OfficeDocumentSettings>
|
||||||
|
<o:AllowPNG></o:AllowPNG>
|
||||||
|
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||||
|
</o:OfficeDocumentSettings>
|
||||||
|
</xml>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="font-family: sans-serif;">
|
||||||
|
<div class="es-wrapper-color">
|
||||||
|
<!--[if gte mso 9]>
|
||||||
|
<v:background xmlns:v="urn:schemas-microsoft-com:vml" fill="t">
|
||||||
|
<v:fill type="tile" color="#ffffff"></v:fill>
|
||||||
|
</v:background>
|
||||||
|
<![endif]-->
|
||||||
|
<table class="es-wrapper" width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-email-paddings" valign="top">
|
||||||
|
<table class="es-content esd-footer-popover" cellspacing="0" cellpadding="0" align="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-stripe" align="center">
|
||||||
|
<table class="es-content-body" style="border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;border-bottom:1px solid transparent;padding:20px 0px;" width="600" cellspacing="0" cellpadding="0" bgcolor="#ffffff" align="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-structure es-p20t es-p40b es-p40r es-p40l" esd-custom-block-id="8537" align="left">
|
||||||
|
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-container-frame" width="518" align="left">
|
||||||
|
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="esd-block-image es-m-txt-c es-p5b" style="font-size:0;padding:10px" align="center"><a target="_blank"><img src="%s" alt="icon" style="display: block;" title="icon" width="30"></a></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr style="background: rgb(249,250,251);padding: 10px;margin-bottom:10px;border-radius:5px;">
|
||||||
|
<td class="esd-block-text es-m-txt-c es-p15t" align="center" style="padding:10px;padding-bottom:30px;">
|
||||||
|
<p>Hey there 👋</p>
|
||||||
|
<p>We received a request to reset password for email: <b>%s</b>. If this is correct, please reset the password clicking the button below.</p> <br/>
|
||||||
|
<a href="%s" class="es-button" target="_blank" style="text-decoration: none;padding:10px 15px;background-color: rgba(59,130,246,1);color: #fff;font-size: 1em;border-radius:5px;">Reset Password</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="position: absolute; left: -9999px; top: -9999px; margin: 0px;"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`, constants.ORGANIZATION_LOGO, toEmail, constants.RESET_PASSWORD_URL+"?token="+token)
|
||||||
|
|
||||||
bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
|
bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
|
||||||
|
|
||||||
return sender.SendMail(Receiver, Subject, bodyMessage)
|
return sender.SendMail(Receiver, Subject, bodyMessage)
|
||||||
|
Reference in New Issue
Block a user