Code Monkey home page Code Monkey logo

casdoor-go-sdk's Introduction

📦⚡️ Casdoor

An open-source UI-first Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML, CAS, LDAP, SCIM, WebAuthn, TOTP, MFA and RADIUS

semantic-release docker pull casbin/casdoor GitHub Workflow Status (branch) GitHub Release Docker Image Version (latest semver)

Go Report Card license GitHub issues GitHub stars GitHub forks Crowdin Discord

Sponsored by

Build auth with fraud prevention, faster.
Try Stytch for API-first authentication, user & org management, multi-tenant SSO, MFA, device fingerprinting, and more.

Online demo

Documentation

https://casdoor.org

Install

How to connect to Casdoor?

https://casdoor.org/docs/how-to-connect/overview

Casdoor Public API

Integrations

https://casdoor.org/docs/category/integrations

How to contact?

Contribute

For casdoor, if you have any questions, you can give Issues, or you can also directly start Pull Requests(but we recommend giving issues first to communicate with the community).

I18n translation

If you are contributing to casdoor, please note that we use Crowdin as translating platform and i18next as translating tool. When you add some words using i18next in the web/ directory, please remember to add what you have added to the web/src/locales/en/data.json file.

License

Apache-2.0

casdoor-go-sdk's People

Contributors

dacongda avatar dirname avatar ebreak avatar halozhy avatar hound672 avatar hsluoyz avatar jk-97 avatar langlanglanglanglang avatar leoil avatar nasa1024 avatar nekotoxin avatar nomeguy avatar notdu avatar pi-kei avatar qianxi0410 avatar qimeila avatar resulte avatar seafeawea avatar sealingp avatar selflocking avatar sh1luo avatar songjf-ttk avatar steve0x2a avatar thaihuynhxyz avatar thanhtinhpas1 avatar towerhe avatar tsaquet avatar waffle-frame avatar wintbiit avatar zhuying1999 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

casdoor-go-sdk's Issues

GetUser() bug, cannot parse response

use GetUser method to get details of the user, and Casdoor returns the content as follows

{
  "owner": "org-xxx",
  "name": "xxxxxx",
  "createdTime": ""
  ...
}

but in

err = json.Unmarshal(respBytes, &response)

The returned content will be Unmarshal to auth.Response first, which is inconsistent with the json format returned by Casdoor, so the user details cannot be actually obtained from GetUser.

casdoor version: v1.45.0
casdoor-go-sdk version: v0.4.0

Missing SDK functionality - /api/set-password

Hi maintainers,

I need the /api/set-password function from the SDK. I would appreciate it a lot if you could help me add it in! It should allow empty "oldPassword".
side note: is there a chance for you to add a flexible function to send http POST requests, similar to how the SDK has DoGetBytesRaw for http GET requests to the casdoor server.

feat: add all missing APIs for all objects

All objects like "organziation", "user", "application", etc.

One object has at least 6 APIs, take "permission" for example:

  • GetGlobalPermissions
  • GetPermissions
  • GetPermission
  • UpdatePermission
  • AddPermission
  • DeletePermission

Existing object properties need to update.

Existing APIs may have changes (like parameters)

Change package name

Note that the semantics of using auth as the package name are not accurate enough. I think casdoor or casdoorsdk should be used as the package name.

/cc @hsluoyz

feat: add test cases for all objects and all operations

Write Go test cases against the demo site: https://demo.casdoor.com/ , remember to restore the original data after test is finished. The tests will be run during CI.

For each type of object (like user, application), do:

  1. Add a new object
  2. List all objects, check if our added object is inside the list
  3. Get the object
  4. Update the object
  5. Delete the object

Refer to: af4ffa4

(This one doesn't pass yet, start by fixing it and make CI pass)

CI failed: https://github.com/casdoor/casdoor-go-sdk/actions/runs/6129983277/job/16638647689

image

casdoorsdk.ParseJwtToken returns crypto/rsa: verification error

deps & envs

  • github.com/casdoor/casdoor-go-sdk v0.17.0
  • go version go1.19.4 darwin/amd64
  • casdoor_example.sql in case you need it ^_^

steps to reproduce

  1. start local casdoor server
  2. create organization (seazhang) & application(seazhang)
  3. call casdoorsdk.InitConfig(...) in my project
  4. call casdoorsdk.AddUser(..)
  5. try to signin in my project, use casdoorsdk as belows

image

it got this error

{
    "err": "crypto/rsa: verification error",
    "level": "error",
    "msg": "ParseJwtToken failed",
    "time": "2023-01-09T23:31:42+08:00",
    "token": {
        "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImNlcnQtYnVpbHQtaW4iLCJ0eXAiOiJKV1QifQ.eyJvd25lciI6InNlYXpoYW5nIiwibmFtZSI6InYtYWRtaW4iLCJjcmVhdGVkVGltZSI6IjIwMjMtMDEtMDkgMjM6MDY6MzgiLCJ1cGRhdGVkVGltZSI6IjIwMjMtMDEtMDkgMjM6MDY6MzgiLCJpZCI6IjAzN2IwMTgzLWMxNWQtNDMxOS04MjkzLTg0NTBhNTBlNGIxNCIsInR5cGUiOiJub3JtYWwtdXNlciIsInBhc3N3b3JkIjoiIiwicGFzc3dvcmRTYWx0IjoiIiwiZGlzcGxheU5hbWUiOiJ2LWFkbWluIiwiZmlyc3ROYW1lIjoiIiwibGFzdE5hbWUiOiIiLCJhdmF0YXIiOiIiLCJwZXJtYW5lbnRBdmF0YXIiOiIiLCJlbWFpbCI6InNlYWxpbmdwQDE2My5jb20iLCJlbWFpbFZlcmlmaWVkIjpmYWxzZSwicGhvbmUiOiIxOTMyODcwMjEzNyIsImxvY2F0aW9uIjoiIiwiYWRkcmVzcyI6W10sImFmZmlsaWF0aW9uIjoiIiwidGl0bGUiOiIiLCJpZENhcmRUeXBlIjoiIiwiaWRDYXJkIjoiIiwiaG9tZXBhZ2UiOiIiLCJiaW8iOiIiLCJyZWdpb24iOiIiLCJsYW5ndWFnZSI6IiIsImdlbmRlciI6IiIsImJpcnRoZGF5IjoiIiwiZWR1Y2F0aW9uIjoiIiwic2NvcmUiOjAsImthcm1hIjowLCJyYW5raW5nIjoxLCJpc0RlZmF1bHRBdmF0YXIiOmZhbHNlLCJpc09ubGluZSI6ZmFsc2UsImlzQWRtaW4iOnRydWUsImlzR2xvYmFsQWRtaW4iOnRydWUsImlzRm9yYmlkZGVuIjpmYWxzZSwiaXNEZWxldGVkIjpmYWxzZSwic2lnbnVwQXBwbGljYXRpb24iOiJ2aXAtc2hhcmUiLCJoYXNoIjoiIiwicHJlSGFzaCI6IiIsImNyZWF0ZWRJcCI6IiIsImxhc3RTaWduaW5UaW1lIjoiIiwibGFzdFNpZ25pbklwIjoiIiwiZ2l0aHViIjoiIiwiZ29vZ2xlIjoiIiwicXEiOiIiLCJ3ZWNoYXQiOiIiLCJmYWNlYm9vayI6IiIsImRpbmd0YWxrIjoiIiwid2VpYm8iOiIiLCJnaXRlZSI6IiIsImxpbmtlZGluIjoiIiwid2Vjb20iOiIiLCJsYXJrIjoiIiwiZ2l0bGFiIjoiIiwiYWRmcyI6IiIsImJhaWR1IjoiIiwiYWxpcGF5IjoiIiwiY2FzZG9vciI6IiIsImluZm9mbG93IjoiIiwiYXBwbGUiOiIiLCJhenVyZWFkIjoiIiwic2xhY2siOiIiLCJzdGVhbSI6IiIsImJpbGliaWxpIjoiIiwib2t0YSI6IiIsImRvdXlpbiI6IiIsImxpbmUiOiIiLCJjdXN0b20iOiIiLCJ3ZWJhdXRobkNyZWRlbnRpYWxzIjpudWxsLCJsZGFwIjoiIiwicHJvcGVydGllcyI6e30sInJvbGVzIjpbXSwicGVybWlzc2lvbnMiOltdLCJsYXN0U2lnbmluV3JvbmdUaW1lIjoiIiwic2lnbmluV3JvbmdUaW1lcyI6MCwibWFuYWdlZEFjY291bnRzIjpudWxsLCJ0b2tlblR5cGUiOiJhY2Nlc3MtdG9rZW4iLCJzY29wZSI6InJlYWQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwMDAiLCJzdWIiOiIwMzdiMDE4My1jMTVkLTQzMTktODI5My04NDUwYTUwZTRiMTQiLCJhdWQiOlsiMzA3M2M5YjZlNmUyZTcyY2M5MWMiXSwiZXhwIjoxNjczODgzMTAxLCJuYmYiOjE2NzMyNzgzMDEsImlhdCI6MTY3MzI3ODMwMSwianRpIjoiYWRtaW4vN2Q5YzE4MDktNTNhNy00YzQ4LTg5YjYtNTQ3YTJkYzNmOTA2In0.P-PH6IJn3gx0shsKnewdUHgHi_b9D7s5A6r9QFtPaN8aFn9p184CHMtJDMp3hS1ov22OBI22409RkAoXxbOIDt1d5tn2ZgZi35nxML4q6lt7NyptkSaoLZ-qrxYl-GJ0Xh6Iu0SZzDsrew-bmWXyPtBgDZPn9wu9AGsFEHlA_X0nkwoRsM2r3QH4Z2Oc4nTz1-EDlxluDxNTQqO9ae6KeGUnKisXB27oGfJPDjFBtNKwxgq021XWKhwbg80jeNK6b8W5-F6djnq5IQKx94JNhp37GpnIF2nJJWYci9FPRTxeN7O67IAgfSHalwcaIK1V6afkUiyslVpoi5O6BPkjUGZZ-na4ZQ4Z6kVDjfRtoj6c3nQ-CvNLLGtfzAlJmmg6O-PhzpVff00ttuqddeQ49br7NimqF-nJcRNwXLuq6IlpYPugmxhxFmAg5HeuBRzQGIp4ZXYSucuugLTOK6TrO16jF2msWO1BbWK3zcT5YGmalp8C6tWBgxwDcFeJnvV_O6hjdrWyvE_0xu2tFS7QI0LruBXcDn3UgH6PtE19VIAgUxc7ga2nvs4c6WeWUS4ziS5Lwgsas5z6R6bpVxiqNbXZNXPTn-_trjhNQMAubdskVe-xUI089ekAoH4RJNfc4AaXeIX7Xz13RVCODA7L9FynoXfZuXx-Nf0CtYr2nx4",
        "token_type": "Bearer",
        "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJvd25lciI6InNlYXpoYW5nIiwibmFtZSI6InYtYWRtaW4iLCJjcmVhdGVkVGltZSI6IjIwMjMtMDEtMDkgMjM6MDY6MzgiLCJ1cGRhdGVkVGltZSI6IjIwMjMtMDEtMDkgMjM6MDY6MzgiLCJpZCI6IjAzN2IwMTgzLWMxNWQtNDMxOS04MjkzLTg0NTBhNTBlNGIxNCIsInR5cGUiOiJub3JtYWwtdXNlciIsInBhc3N3b3JkIjoiIiwicGFzc3dvcmRTYWx0IjoiIiwiZGlzcGxheU5hbWUiOiJ2LWFkbWluIiwiZmlyc3ROYW1lIjoiIiwibGFzdE5hbWUiOiIiLCJhdmF0YXIiOiIiLCJwZXJtYW5lbnRBdmF0YXIiOiIiLCJlbWFpbCI6InNlYWxpbmdwQDE2My5jb20iLCJlbWFpbFZlcmlmaWVkIjpmYWxzZSwicGhvbmUiOiIxOTMyODcwMjEzNyIsImxvY2F0aW9uIjoiIiwiYWRkcmVzcyI6W10sImFmZmlsaWF0aW9uIjoiIiwidGl0bGUiOiIiLCJpZENhcmRUeXBlIjoiIiwiaWRDYXJkIjoiIiwiaG9tZXBhZ2UiOiIiLCJiaW8iOiIiLCJyZWdpb24iOiIiLCJsYW5ndWFnZSI6IiIsImdlbmRlciI6IiIsImJpcnRoZGF5IjoiIiwiZWR1Y2F0aW9uIjoiIiwic2NvcmUiOjAsImthcm1hIjowLCJyYW5raW5nIjoxLCJpc0RlZmF1bHRBdmF0YXIiOmZhbHNlLCJpc09ubGluZSI6ZmFsc2UsImlzQWRtaW4iOnRydWUsImlzR2xvYmFsQWRtaW4iOnRydWUsImlzRm9yYmlkZGVuIjpmYWxzZSwiaXNEZWxldGVkIjpmYWxzZSwic2lnbnVwQXBwbGljYXRpb24iOiJ2aXAtc2hhcmUiLCJoYXNoIjoiIiwicHJlSGFzaCI6IiIsImNyZWF0ZWRJcCI6IiIsImxhc3RTaWduaW5UaW1lIjoiIiwibGFzdFNpZ25pbklwIjoiIiwiZ2l0aHViIjoiIiwiZ29vZ2xlIjoiIiwicXEiOiIiLCJ3ZWNoYXQiOiIiLCJmYWNlYm9vayI6IiIsImRpbmd0YWxrIjoiIiwid2VpYm8iOiIiLCJnaXRlZSI6IiIsImxpbmtlZGluIjoiIiwid2Vjb20iOiIiLCJsYXJrIjoiIiwiZ2l0bGFiIjoiIiwiYWRmcyI6IiIsImJhaWR1IjoiIiwiYWxpcGF5IjoiIiwiY2FzZG9vciI6IiIsImluZm9mbG93IjoiIiwiYXBwbGUiOiIiLCJhenVyZWFkIjoiIiwic2xhY2siOiIiLCJzdGVhbSI6IiIsImJpbGliaWxpIjoiIiwib2t0YSI6IiIsImRvdXlpbiI6IiIsImxpbmUiOiIiLCJjdXN0b20iOiIiLCJ3ZWJhdXRobkNyZWRlbnRpYWxzIjpudWxsLCJsZGFwIjoiIiwicHJvcGVydGllcyI6e30sInJvbGVzIjpbXSwicGVybWlzc2lvbnMiOltdLCJsYXN0U2lnbmluV3JvbmdUaW1lIjoiIiwic2lnbmluV3JvbmdUaW1lcyI6MCwibWFuYWdlZEFjY291bnRzIjpudWxsLCJ0b2tlblR5cGUiOiJyZWZyZXNoLXRva2VuIiwic2NvcGUiOiJyZWFkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDAwIiwic3ViIjoiMDM3YjAxODMtYzE1ZC00MzE5LTgyOTMtODQ1MGE1MGU0YjE0IiwiYXVkIjpbIjMwNzNjOWI2ZTZlMmU3MmNjOTFjIl0sImV4cCI6MTY3MzI3ODMwMSwibmJmIjoxNjczMjc4MzAxLCJpYXQiOjE2NzMyNzgzMDEsImp0aSI6ImFkbWluLzdkOWMxODA5LTUzYTctNGM0OC04OWI2LTU0N2EyZGMzZjkwNiJ9.XzlUMNYWG1-6SHSpHkdKWlfKwnm-GqRlKoVGiTxTKBIQV_6fsBcshBRV8b7bgCJADANzzVNvZoMike5mqASCywDmjnYrogvX_UODEj_aG5D-8YFDNziicirLyZDWBSrbEqjDSdKVVsoRXzKvDdyre1tErKZFVibwZ1c-wtxkZDL0iofbuPOEMOk6poySLllYPwmJJXFb1whXTkL1d9jE_F0mdtcgow8oN_OWGE7D8pydrsHkQ_b7DMaAMTtj-jFaEuevLL2WJxXWTUQGiXNUAPcnT8mgXSa1c_NfXdmpeyLjIOVWNGGbHdNgtP5ekiOEvLzDp-ocxv4WLKu-XO1R81eUbFTGgWNW7m9pbGdYJdJg1ix0llZXDqEADzmhivp3MkkB-DYNkbyqu_C1ZODUCsu132xyMZ6YH-f22GDUeklo_dfLUO1hMJkiQ-ZwwYGNPGTOflXkfe2UA19nhSjlezaf33tYwnoyCAUUkDjTqwYyzyOGq20H1w07JQ-wDAy4zuWb-UDxoI7K6WRvosJ-QqPjo7gxjidAz4-HKiufyWSoY1e0hSMPKyaX2uPcfuYpOFN_wv92S_9f-r7GbJ2DEBXuOzxoz4pn2WICHQj46-EM5ksrjp8utq1yLYFSeFi4Bw2e-O52r_Xsn4o5UhtuoQ3ElqSPGIisbE5S5vYy5c8",
        "expiry": "2023-01-16T23:31:42.004885+08:00"
    }
}

strange things

  • i can use the same user&pass to signin successful by directly access http://localhost:7001/login/seazhang
    image
    image

  • i can't use the same user&pass to signin in my project
    image
    image

  • complete code about SignInCallback api in my project

type SignInCallbackRequest struct {
	Code  string `json:"code"`
	State string `json:"state"`
}

type SignInCallbackResponse struct {
	AccessToken string          `json:"access_token"`
	User        casdoorsdk.User `json:"user"`
}

func (s *Server) SignInCallback(c context.Context, ctx *app.RequestContext) {
	req := &SignInCallbackRequest{}
	if err := ctx.Bind(req); err != nil {
		s.abortNotOK(c, ctx, http.StatusBadRequest, err)
		return
	}

	token, err := casdoorsdk.GetOAuthToken(req.Code, req.State)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"token": token,
			"code":  req.Code,
			"state": req.State,
			"err":   err,
		}).Errorf("GetOAuthToken failed")
		s.abortNotOK(c, ctx, http.StatusUnauthorized, err)
		return
	}

	claims, err := casdoorsdk.ParseJwtToken(token.AccessToken)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"token": token,
			"err":   err,
		}).Errorf("ParseJwtToken failed")
		s.abortNotOK(c, ctx, http.StatusUnauthorized, err)
		return
	}

	// _, err = object.UpdateMemberOnlineStatus(&claims.User, true, util.GetCurrentTime())
	// if err != nil {
	// 	logrus.WithFields(logrus.Fields{
	// 		"user": claims.User,
	// 		"err":  err,
	// 	}).Errorf("UpdateMemberOnlineStatus failed")
	// 	s.abortNotOK(c, ctx, http.StatusUnauthorized, err)
	// 	return
	// }

	respData := &SignInCallbackResponse{
		AccessToken: claims.AccessToken,
		User:        claims.User,
	}
	s.abortOK(c, ctx, respData)
}

Refresh token and access token are interchangeable

Version: 0.35.1

If you pass either refresh token or access token to casdoorsdk.ParseJwtToken(token) then token will pass verification and there's no good way to distinct one from another using returned casdoorsdk.Claims. The downside of this is that security risks are higher.

You can use jwt parser directly without casdoor sdk to ensure token type. Refresh tokens have a claim TokenType that equal to refresh-token

bug: err url of subscriptionApi

bug: err url of subscriptionApi

func (c *Client) GetPaginationSubscriptions(p int, pageSize int, queryMap map[string]string) ([]*Subscription, int, error) {
queryMap["owner"] = c.OrganizationName
queryMap["p"] = strconv.Itoa(p)
queryMap["pageSize"] = strconv.Itoa(pageSize)
url := c.GetUrl("get-providers", queryMap)
response, err := c.DoGetResponse(url)
if err != nil {
return nil, 0, err
}
subscriptions, ok := response.Data.([]*Subscription)
if !ok {
return nil, 0, errors.New("response data format is incorrect")
}
return subscriptions, int(response.Data2.(float64)), nil
}

get-providers should be get-subscriptions

Unable to unmarshal response data after Casdoor using RespnseOk

after casdoor/casdoor@a6f803a, casdoor-go-sdk codes like

func GetUser(name string) (*User, error) {
	queryMap := map[string]string{
		"id": fmt.Sprintf("%s/%s", authConfig.OrganizationName, name),
	}

	url := GetUrl("get-user", queryMap)

	bytes, err := DoGetBytesRaw(url)
	if err != nil {
		return nil, err
	}

	var user *User
	err = json.Unmarshal(bytes, &user)
	if err != nil {
		return nil, err
	}
	return user, nil
}

No longer works (return empty struct / panic) because response format has changed from data model alone to wrapped response json. Take the user.go#GetUser() above as example.

Before casdoor/casdoor@a6f803a /api/get-user returns just user modal.

image

Then after it returns standard reponse modal in which user modal is wrapped in data field.

image

Quite a lot apis in casdoor-go-sdk has been influenced, such as user.go, resource.go...... Almost anywhere code like

bytes, err := DoGetBytesRaw(url)
if err != nil {
	return nil, err
}

var user *User
err = json.Unmarshal(bytes, &user)

encounters this.

By the way I noticed that actually DoGetBytesRaw() already unmarshaled response bytes to standard response data modal and then return the original reponse bytes. Maybe changing this would help.

// DoGetBytesRaw is a general function to get response from param url through HTTP Get method.
func DoGetBytesRaw(url string) ([]byte, error) {
	respBytes, err := doGetBytesRawWithoutCheck(url)
	if err != nil {
		return nil, err
	}

	var response Response
	err = json.Unmarshal(respBytes, &response)
	if err == nil && response.Status == "error"{
		return nil, errors.New(response.Msg)
	}

	return respBytes, nil
}

Maybe more sdks like java-sdk, js-sdk or rust-sdk also have this issue, are the next steps of casdoor/casdoor@a6f803a underway?

Unmarshal error while parsing wrong answer from casdoor

Hello!

I receive unmarshal error while I getting not json response from casdoor service.
For example:

	users, err := casdoorsdk.GetUsers()
	if err != nil {
		log.Fatalf("get users: %v", err)  // get users: invalid character '<' looking for beginning of value
	}

Why casdoor answered like that is an another question :)
But, I'd like to get from casdoor sdk more specific error, for instance: ErrCasdoorInternal.
In that case I will be able to write errors checking like that:

users, err := casdoorsdk.GetUsers()
if errors.Is(err, ErrCasdoorInternal) {
   // 
}

If you don't mind I'd make PR for fixing that.

Bug in GetToken API

Get token API of Casdoor accept id in the query parameter. ID is combination of owner and name of the token as documented here. https://door.casdoor.com/swagger/#/Token%20API/ApiController.GetToken

However in GetToken implementation of this SDK, it is assumed that Organization is the owner https://github.com/casdoor/casdoor-go-sdk/blob/master/casdoorsdk/token.go#L87

queryMap := map[string]string{
"id": fmt.Sprintf("%s/%s", c.OrganizationName, name),
}

Looks like this is not the case all the time. In my case, I am observing that even though organization name is built-in, owner name of the token is admin.

As a result, GetToken is sending wrong id to Casdoor server.

Attaching a sample response of get-token API that explains that ower value can be different from organization name.

Screenshot 2024-03-07 at 01 44 49

Another weird thing I am observing in get-token API is that even if wrong ID is sent, no error is returned from API. Instead response code is 200 with following json payload:

{
    "status": "ok",
    "msg": "",
    "sub": "",
    "name": "",
    "data": null,
    "data2": null
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.